2017-08-13 81 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