/* * Static and dynamic method dispatch in Kotlin * Functions defined (and overridden) have dynamic dispatch * The function called is dependent on the class of the * underlying object at the time it was created, regardless * of what is has been cast to * * Extension functions have static dispatch. * The function called is dependent on the type visible at the * time of the call. * Also, if there is a member funtion and an extension function * of the same name, the member wins! * *@author gtowell * created: Aug 5, 2021 */ // a class open class Shape // an inheriting class class Rectangle: Shape() // extension functions for each fun Shape.getName() = "Shape" fun Rectangle.getName() = "Rectangle" open class Shape2 { val qq = "QQ" open fun getName() = "Shape2" fun getName2() = "Shape2" } class Rectangle2: Shape2() { override fun getName() = "Rectangle2" } fun Shape2.getName2() = "ExtnName2" fun Shape2.getName3() = "ExtnName3 " + this.qq + " " + this.javaClass.simpleName var Shape2.extensionProperty : Int get() = extensionProperty * extensionProperty set(v:Int) { extensionProperty = v } fun main() { // static method dispatch for extension functions val r = Rectangle() println(r.getName()) val s : Shape = r println(s.getName()) // dynamic method dispatch for member functions val r2 = Rectangle2() println(r.getName()) val s2 : Shape2 = r2 println(s2.getName()) // the member function wins agains the extension function println(s2.getName2()) println(r2.getName2()) // extension functions are inherited; but note that static // dispatch of the method does NOT mean that method calls made // inside the function have static dispatch!! val r3 = Rectangle2() val s3 = Shape2() println(r3.getName3()) println(s3.getName3()) }