我想在实现接口的类中使用函数参数的默认值,如下所示:
interface FileStoreService {
fun storeFile(path: String, payload: InputStream, type: MediaType, replace: Boolean = true)
}
Run Code Online (Sandbox Code Playgroud)
class LocalFileStoreService : FileStoreService {
override fun storeFile(path: String, payload: InputStream, type: MediaType, replace: Boolean /* ?? */) {
// ....
}
}
Run Code Online (Sandbox Code Playgroud)
现在,这是编译的内容,这是未编译的内容:
KO:不允许重写函数为其参数指定默认值
class LocalFileStoreService : FileStoreService {
override fun storeFile(path: String, payload: InputStream, type: MediaType, replace: Boolean = true) {
// ....
}
}
Run Code Online (Sandbox Code Playgroud)
KO:“LocalFileStoreService”类不是抽象的,也没有实现抽象成员 public Abstract fun storeFile(path: String, Payload: InputStream, type: MediaType): 在 fqn...FileStoreService 中定义的单元
class LocalFileStoreService : FileStoreService {
override fun storeFile(path: String, payload: InputStream, type: MediaType, replace: Boolean) {
// ....
}
}
Run Code Online (Sandbox Code Playgroud)
好的:
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) {
// ....
}
}
Run Code Online (Sandbox Code Playgroud)
这是预期的行为吗?有没有更好的方法来管理接口中的默认参数值?
你所描述的很奇怪,因为通过尝试用 Kotlin 1.4.20 重现它,我没有看到相同的行为。
下面的代码工作正常:
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")
}
Run Code Online (Sandbox Code Playgroud)
如果我取消注释没有布尔参数的函数,编译会崩溃,因为该方法不是从接口继承的。
一般来说,如果您在接口级别定义默认值,那么更改特定实现的默认值将是一个坏主意,因为这会破坏 API 约定。
编辑
请注意,从注释函数中删除 override 关键字将产生有效的代码,因为它成为特定于实现的函数。不过,我发现这种行为很危险,因为以下程序:
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")
}
Run Code Online (Sandbox Code Playgroud)
然后将产生以下输出:
It works ! Received: Hello and true
That's odd... received: Hello
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13334 次 |
| 最近记录: |