简体   繁体   English

Kotlin 接口与默认 function 参数值

[英]Kotlin Interface with default function argument value

I would like to use a default value for a function parameter in a class implementing an interface, like this:我想在实现接口的 class 中为 function 参数使用默认值,如下所示:

interface FileStoreService {
    fun storeFile(path: String, payload: InputStream, type: MediaType, replace: Boolean = true)
}
class LocalFileStoreService : FileStoreService {

    override fun storeFile(path: String, payload: InputStream, type: MediaType, replace: Boolean /* ?? */) {
        // ....
    }
}

Now here is what compiles and here is what doesn't compile:现在这是编译的,这是不编译的:

KO : An overriding function is not allowed to specify default values for its parameters KO :不允许覆盖 function 为其参数指定默认值

class LocalFileStoreService : FileStoreService {

    override fun storeFile(path: String, payload: InputStream, type: MediaType, replace: Boolean = true) {
        // ....
    }
}

KO : Class 'LocalFileStoreService' is not abstract and does not implement abstract member public abstract fun storeFile(path: String, payload: InputStream, type: MediaType): Unit defined in fqn...FileStoreService KO : Class 'LocalFileStoreService' 不是抽象的,也没有实现抽象成员 public abstract fun storeFile(path: String, payload: InputStream, type: MediaType): Unit defined in fqn...FileStoreService

class LocalFileStoreService : FileStoreService {

    override fun storeFile(path: String, payload: InputStream, type: MediaType, replace: Boolean) {
        // ....
    }
}

OK :好的

class LocalFileStoreService : FileStoreService {

    override fun storeFile(path: String, payload: InputStream, type: MediaType) {
        storeFile(path, payload, type, true)
    }

    override fun storeFile(path: String, payload: InputStream, type: MediaType, replace: Boolean) {
        // ....
    }
}

Is this the expected behaviour?这是预期的行为吗? Is there a better way to manage default parameter values in interfaces?有没有更好的方法来管理接口中的默认参数值?

What you describe is odd, because by trying to reproduce it with Kotlin 1.4.20, I do not see the same behaviour.您所描述的很奇怪,因为通过尝试使用 Kotlin 1.4.20 重现它,我看不到相同的行为。

Below code is working fine:下面的代码工作正常:

interface Test {
    fun test(p1: String, p2: Boolean = true)
}

class TestImpl : Test {
    // below commented function breaks compilation
    //override fun test(p1: String) = println("That's odd... received: $p1")

    // You cannot overwrite default value, that would break interface contract
    override fun test(p1: String, p2: Boolean) = println("It works ! Received: $p1 and $p2")
}

fun main() {
    // Default value for second parameter is deduced from interface signature 
    TestImpl().test("Hello")
}

If I uncomment the function without boolean parameter, compilation crashes, because the method does not inherit from the interface.如果我取消注释没有 boolean 参数的 function ,编译会崩溃,因为该方法不是从接口继承的。

Generally speaking, if you define default values at interface level, it would be a bad idea to change the default value for a specific implementation, because it would break API contract.一般来说,如果您在接口级别定义默认值,那么更改特定实现的默认值将是一个坏主意,因为它会破坏 API 合同。

Edit编辑

Note that removing override keyword from commented function would produce valid code, because it becomes a function specific to the implementation.请注意,从注释 function 中删除 override 关键字将产生有效代码,因为它成为特定于实现的 function。 I find such behavior dangerous, though, because the following program:不过,我发现这种行为很危险,因为以下程序:

interface Test {
    fun test(p1: String, p2: Boolean = true)
}

class TestImpl : Test {
    fun test(p1: String) = println("That's odd... received: $p1")
    override fun test(p1: String, p2: Boolean) = println("It works ! Received: $p1 and $p2")
}

fun main() {
    val t : Test = TestImpl()
    t.test("Hello")
    (t as TestImpl).test("Hello")
}

will then produce this output:然后将产生这个 output:

It works ! Received: Hello and true
That's odd... received: Hello

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM