Kotlin:当扩展函数隐藏类的默认实现?
问题描述:
我试图弄清当重写一个现有的类功能,具有相同签名的扩展功能 - 会生效吗?Kotlin:当扩展函数隐藏类的默认实现?
这里是我的示例代码:
fun String.toUpperCase(): String = "ext. function impl."
fun main(args: Array<String>) {
println("Hello".toUpperCase()) // ext. function impl.
println(MyClass().toUpperCase()) // class impl.
}
class MyClass {
fun toUpperCase() : String {
return "class impl."
}
}
fun MyClass.toUpperCase() : String {
return "ext. function impl."
}
所以:
- 什么是规则?什么时候会被调用?
- 我怎样才能覆盖这个决定?可能吗?
答
从the Kotlin docs(着重不矿):
如果一个类的成员函数,以及扩展函数被定义,其具有相同的接收器类型,相同的名称,并适用于给出的论点,成员总是赢得。
您的字符串示例工作的原因是因为该库提供的String.toUpperCase()
是已经的扩展功能,而不是一个成员函数。文档没有说明这里发生了什么,但似乎合理的假设当地的延伸胜出。
我不认为有任何方法可以改变这种行为。这可能是最好的,因为它违反了许多情况下最不惊讶的原则(即难以理解的行为)。
这种行为实际上在'kotlin-stdlib'的一些地方发生了变化(例如[here](https://github.com/JetBrains/kotlin/blob/master/libraries/stdlib/src/generated/_Maps)。 kt#L133)),但这是通过'kotlin.internal.HidesMembers'完成的,显然这是一个内部工具,不适用于第三方代码。这很好。 – hotkey