Home > Enterprise >  Kotlin: How to call super implementation of an extension method
Kotlin: How to call super implementation of an extension method

Time:11-17

In Kotlin I have code like the following:

open class A {
    protected open fun B.doSomething() {}
}

class B {}

class C : A() {

    override fun B.doSomething() {
        print("first, do some C-specific logic")
        print("now try to call super implementation. How?")
        super.doSomething() // does not compile
        super<A>.doSomething() // does not compile
        super<B>.doSomething() // does not compile
    }
}

And I would like to know, how I can call the superclass implementation of doSomething() in this case? Or is it not possible at all to call a super implementation for an extension function in kotlin?

CodePudding user response:

This problem has been reported in KT-11488. It is currently not possible. The Kotlin spec says that the candidate members for a super-form call is found in the following way:

For a callable f with an explicit basic super-form receiver super in a classifier declaration with supertypes A1, A2, … , AN the following sets are considered for non-emptiness:

  • Non-extension member callables named f of type A1;
  • Non-extension member callables named f of type A2;
  • …;
  • Non-extension member callables named f of type AN.

If at least two of these sets are non-empty, this is a compile-time error. Otherwise, the non-empty set (if any) is analyzed as usual.

For a callable f with an explicit extended super-form receiver super<A> the following sets are analyzed (in the given order):

  • Non-extension member callables named f of type A.

As you can see, only "non-extension member callables" are considered. Extension functions are not considered at all.

For now, you can do a workaround like this (something similar is also suggested in the ticket):

open class A {
    protected open fun B.doSomething() =
        bDoSomething(this)

    // make a non-extension function to put A's implementation in there
    protected fun bDoSomething(receiver: B) {
        print("A implementation")
    }
}

class C : A() {

    override fun B.doSomething() {
        print("first, do some C-specific logic")
        super.bDoSomething(this) // call the non-extension function
    }
}
  • Related