3

In kotlin Declaraing extensions as members, what does it mean "the dispatch of such functions is virtual with regard to the dispatch receiver type, but static with regard to the extension receiver type."

Is this mean that "the extension function doesn't follows its reciever's class type. It follows parameter type(?in this code call method parameter)."

please give your warmhearted and generous advice

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
}

1 Answers1

2

Since you have linked the documentation, I take it that you have read the following part

The instance of the class in which the extension is declared is called dispatch receiver, and the instance of the receiver type of the extension method is called extension receiver.

After you have understood the above terminology, you need to understand following points

  • If you don't know about virtual methods read this
  • Extensions are resolved statically. Consider the following code block

    fun call(b: Base) {
         // This will always call extension function defined on the Base class
         // even if you pass an object of Derived class
         b.printFunctionInfo()   // call the extension function
    }
    
    // This calls the printFunctionInfo defined on the Base, even though we pass Derived
    DerivedCaller().call(Derived()) 
    

Now to your question

the dispatch of such functions is virtual with regard to the dispatch receiver type, but static with regard to the extension receiver type.

With the Extensions are resolved statically point we have established that no matter which object you pass (Base or Derived) the call function will always invoke an extension function defined on the Base type.

But which extension function will be invoked? one in the Base class or the one in Derived class ?

This depends on the type of object which invokes the call function, if you invoke the call with an Object of Base then the extension in the base class will be invoked and if you use the Derived object then the extension in Derived class will be invoked.

mightyWOZ
  • 7,946
  • 3
  • 29
  • 46