Search code examples
kotlindelegation

This not referring to the original object using Kotlins class delegation


I am confused how delegation works in Kotlin. Wikipedia says:

With language-level support for delegation, this is done implicitly by having self in the delegate refer to the original (sending) object, not the delegate (receiving object).

Given the following Code:

interface BaseInterface {
    fun print()
}

open class Base() : BaseInterface {
    override fun print() { println(this) }
}

class Forwarded()  {
    private val base = Base()

    fun print() { base.print() }
}

class Inherited() : Base() {}

class Delegated(delegate: BaseInterface) : BaseInterface by delegate

fun main(args: Array<String>) {
    print("Forwarded: ")
    Forwarded().print();
    print("Inherited: ")
    Inherited().print();
    print("Delegated: ")
    Delegated(Base()).print();
}

I get this output:

Forwarded: Base@7440e464
Inherited: Inherited@49476842
Delegated: Base@78308db1

I'd expect Delegated to return Delegated because self/this should refer to the original object. Do I get it wrong or is Kotlins delegation different?


Solution

  • Kotlin delegation is very simple - it generates all interface methods and implicitly invokes it on delegated object, except for methods explicitly overriden by the user.

    Your example is functionally the same as:

    class Delegated(delegate: BaseInterface) : BaseInterface{
        // when generating bytecode kotlin assigns delegate object to internal final variable
        // that is not visible at compile time
        private val d = delegate
    
        override fun print(){
            d.print()
        }
    }
    

    So it's pretty clear why it prints Base.