I've read this answer but I'm still confused. When looking at this example in the docs...
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
}
And regarding this quote
An instance of a class in which the extension is declared is called a dispatch receiver, and an instance of the receiver type of the extension method is called an extension receiver.
I assume that only instances of Base() and Derived() can be extension receivers, because we only defined extensions for those two classes. And I assume that only instances of BaseCaller() and DerivedCaller() can be dispatch receivers, because we only declare extensions inside those classes.
My confusion stems from the two comments at the bottom of the example where it says "dispatch receiver is resolved virtually" and "extension receiver is resolved statically". Are they referring to DerivedCaller() in both cases? Is DerivedCaller() a dispatch receiver in one line and an extension receiver in the next? How can it be an extension receiver if we never declare any extensions for it? Or are they referring to Base() as the dispatch receiver and Derived() as the extension receiver? How can Base() be a dispatch receiver, if it never declares any extensions?
I know that call() always resolves statically to use an instance of Base, and I know the version of Base.printFunctionInfo() will depend on what object I call the call() method on (either BaseCaller() or DerivedCaller()), but I'm confused about what those comments are saying. Thanks in advance!