Kotlin:如何调用扩展方法的超级实现

use*_*501 4 extension-methods overriding kotlin

在 Kotlin 中我有如下代码:

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
    }
}
Run Code Online (Sandbox Code Playgroud)

我想知道,在这种情况下如何调用 doSomething() 的超类实现?或者根本不可能在 kotlin 中调用扩展函数的超级实现?

Swe*_*per 5

KT-11488中已报告此问题。目前这是不可能的。Kotlin 规范表示,super-form 调用的候选成员是通过以下方式找到的:

\n
\n

对于在具有超类型 A1、A2、\xe2\x80\xa6 、 AN 的分类器声明中f具有显式基本超形式接收器的super可调用函数,以下\n集合被视为非空:

\n
    \n
  • f命名为类型的非扩展成员可调用项A1
  • \n
  • f命名为 type 的非扩展成员可调用项A2
  • \n
  • \xe2\x80\xa6;
  • \n
  • f名为类型 的非扩展成员可调用项AN
  • \n
\n

如果这些集合中至少有两个非空,则这是一个编译时错误。否则,将照常分析非空集(如果有)。

\n

对于f具有显式扩展超形式接收器的可调用对象super<A>,将分析以下集合(按给定顺序):

\n
    \n
  • f名为类型 的非扩展成员可调用项A
  • \n
\n
\n

如您所见,仅考虑“非扩展成员可调用对象”。根本不考虑扩展功能。

\n

现在,您可以采取这样的解决方法(票证中也建议了类似的方法):

\n
open class A {\n    protected open fun B.doSomething() =\n        bDoSomething(this)\n\n    // make a non-extension function to put A\'s implementation in there\n    protected fun bDoSomething(receiver: B) {\n        print("A implementation")\n    }\n}\n\nclass C : A() {\n\n    override fun B.doSomething() {\n        print("first, do some C-specific logic")\n        super.bDoSomething(this) // call the non-extension function\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n