2017-08-13 82 views
3

我试图弄清当重写一个现有的类功能,具有相同签名的扩展功能 - 会生效吗?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." 
} 

所以:

  • 什么是规则?什么时候会被调用?
  • 我怎样才能覆盖这个决定?可能吗?

回答

3

the Kotlin docs(着重矿):

如果一个类的成员函数,以及扩展函数被定义,其具有相同的接收器类型,相同的名称,并适用于给出的论点,成员总是赢得

您的字符串示例工作的原因是因为该库提供的String.toUpperCase()已经的扩展功能,而不是一个成员函数。文档没有说明这里发生了什么,但似乎合理的假设当地的延伸胜出。


我不认为有任何方法可以改变这种行为。这可能是最好的,因为它违反了许多情况下最不惊讶的原则(即难以理解的行为)。

+1

这种行为实际上在'kotlin-stdlib'的一些地方发生了变化(例如[here](https://github.com/JetBrains/kotlin/blob/master/libraries/stdlib/src/generated/_Maps)。 kt#L133)),但这是通过'kotlin.internal.HidesMembers'完成的,显然这是一个内部工具,不适用于第三方代码。这很好。 – hotkey