kotlin - 具有默认函数参数值的 Kotlin 接口
问题描述
我想在实现接口的类中为函数参数使用默认值,如下所示:
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 /* ?? */) {
// ....
}
}
现在这是编译的,这是不编译的:
KO : 不允许重写函数为其参数指定默认值
class LocalFileStoreService : FileStoreService {
override fun storeFile(path: String, payload: InputStream, type: MediaType, replace: Boolean = true) {
// ....
}
}
KO:“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) {
// ....
}
}
好的:
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) {
// ....
}
}
这是预期的行为吗?有没有更好的方法来管理接口中的默认参数值?
解决方案
您所描述的很奇怪,因为通过尝试使用 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")
}
如果我取消注释没有布尔参数的函数,编译会崩溃,因为该方法不是从接口继承的。
一般来说,如果您在接口级别定义默认值,那么更改特定实现的默认值将是一个坏主意,因为它会破坏 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")
}
然后将产生这个输出:
It works ! Received: Hello and true
That's odd... received: Hello
推荐阅读
- angular - 如何在角度 7 中的 DatePipe 'short' 中设置您自己的 stringFormat?
- java - 无法从我在 BIRT 的报告中引用 Java 类
- javascript - 如何从圆的最外圆弧画线
- php - Wordpress + Woocommerce + 终极会员。使用最终会员注册表单数据更新客户字段
- typescript - Mocha - 对装饰器的实验性支持是一项可能在未来版本中更改的功能
- outlook - Office 加载项在仍在安装时从功能区中消失
- assembly - 为什么在这种情况下 rax 和 rdi 的工作方式相同?
- typescript - Vue: can't use render props with TSX
- javascript - Bash 脚本没有将 Javascript 命令保留到 EOF
- java - Scala - 模式匹配布尔值和默认值时无法访问的代码