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 receiversuper
in a classifier declaration with supertypes A1, A2, … , AN the following sets are considered for non-emptiness:
- Non-extension member callables named
f
of typeA1
;- Non-extension member callables named
f
of typeA2
;- …;
- Non-extension member callables named
f
of typeAN
.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 receiversuper<A>
the following sets are analyzed (in the given order):
- Non-extension member callables named
f
of typeA
.
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
}
}