我已經閱讀了這個答案,但我仍然感到困惑。在檔案中查看此示例時...
open class Base { }
class Derived : Base() { }
open class BaseCaller {
open fun Base.printFunctionInfo() {
println("Base extension function in BaseCaller")
}
open fun Derived.printFunctionInfo() {
println("Derived extension function in BaseCaller")
}
fun call(b: Base) {
b.printFunctionInfo() // call the extension function
}
}
class DerivedCaller: BaseCaller() {
override fun Base.printFunctionInfo() {
println("Base extension function in DerivedCaller")
}
override fun Derived.printFunctionInfo() {
println("Derived extension function in DerivedCaller")
}
}
fun main() {
BaseCaller().call(Base()) // "Base extension function in BaseCaller"
DerivedCaller().call(Base()) // "Base extension function in DerivedCaller" - dispatch receiver is resolved virtually
DerivedCaller().call(Derived()) // "Base extension function in DerivedCaller" - extension receiver is resolved statically
}
關于這個報價
宣告了擴展的類的實體稱為調度接收器,擴展方法的接收器型別的實體稱為擴展接收器。
我假設只有 Base() 和 Derived() 的實體可以是擴展接收器,因為我們只為這兩個類定義了擴展。我假設只有 BaseCaller() 和 DerivedCaller() 的實體可以作為調度接收器,因為我們只在這些類中宣告擴展。
我的困惑源于示例底部的兩條評論,其中說“調度接收器是虛擬決議的”和“擴展接收器是靜態決議的”。在這兩種情況下,他們都指的是 DerivedCaller() 嗎?DerivedCaller() 是一行中的調度接收器,下一行中是擴展接收器嗎?如果我們從不為它宣告任何擴展,它怎么能成為擴展接收器呢?或者他們將 Base() 稱為調度接收器,將 Derived() 稱為擴展接收器?如果 Base() 從未宣告任何擴展,它如何成為調度接收器?
我知道 call() 總是靜態決議以使用 Base 的實體,并且我知道 Base.printFunctionInfo() 的版本將取決于我呼叫 call() 方法的物件(BaseCaller() 或 DerivedCaller()) ,但我對這些評論所說的內容感到困惑。提前致謝!
uj5u.com熱心網友回復:
我最初對檔案中的這兩條評論感到困惑
- “調度接收器是虛擬解決的”
- “擴展接收器是靜態決議的”
在第一條注釋中,“調度接收器”指的是DerivedCaller()實體。它是虛擬的,因為他們可以call()在BaseCaller()實體或DerivedCaller()實體上呼叫該方法(但他們最終在DerivedCaller()實體上呼叫了它)。第一個注釋與呼叫哪個擴展方法有關,one inBaseCaller或 one inDerivedCaller
在第二條注釋中,“擴展接收器”指的Derived()是傳入call(). 第二條注釋與從DerivedCaller類內部呼叫哪個成員函式 get 相關。的Base.printFunctionInfo()或Derived.printFunctionInfo()。在這種情況下,擴展接收器是靜態決議的,所以不是使用Derived()它而是使用它,Base()因為這就是我的擴展函式的設定方式(并且擴展函式總是靜態決議的)。
uj5u.com熱心網友回復:
這是很容易理解,如果我們認識到,Base.printFunctionInfo()和Derived.printFunctionInfo()有很多不同的功能,只是名稱相同。如果我們重命名它們,這個例子就很明顯了:
open class BaseCaller {
open fun Base.printFunctionInfoForBase() {
println("Base extension function in BaseCaller")
}
open fun Derived.printFunctionInfoForDerived() {
println("Derived extension function in BaseCaller")
}
fun call(b: Base) {
b.printFunctionInfoForBase() // call the extension function
}
}
class DerivedCaller: BaseCaller() {
override fun Base.printFunctionInfoForBase() {
println("Base extension function in DerivedCaller")
}
override fun Derived.printFunctionInfoForDerived() {
println("Derived extension function in DerivedCaller")
}
}
在call()我們只有一個Base物件,所以我們只能呼叫printFunctionInfoForBase(),但我們不能printFunctionInfoForDerived()在那里呼叫。然后,我們清楚地看到printFunctionInfoForDerived()在這段代碼中的任何地方都從未呼叫過。
換句話說,Base.printFunctionInfo()和Derived.printFunctionInfo()是函式的兩個多載。 DerivedCaller提供覆寫的BaseCaller功能。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/395886.html
上一篇:替代多重繼承來擴展庫
下一篇:如何將json物件添加到引數
