Kotlin:子类如何在超级构造函数调用中使用父级的扩展函数?
子类如何在lambda字段中使用其父类的扩展函数?
考虑这个父类:
abstract class Parent(val field: Int.() -> Any) { fun Int.print() = println(this) }
而这个孩子:
class Child : Parent({ print() // DOESN'T COMPILE this.print() // DOESN'T COMPILE 5.print() // DOESN'T COMPILE val value = 5 value.print() // DOESN'T COMPILE })
你不能在Child
超级构造函数调用参数中使用Parent
的扩展的原因是它的Parent
部分在那个时候还没有初始化,因此不能用作扩展的调度接收器 。
成员扩展函数可以使用eclosing类的成员,这意味着他们需要调用的类的实例,并且不能在自己的构造函数参数中使用该实例。
否则,可以在Child
成员内部的任何位置和构造函数(或init
块)中使用Parent
的扩展,因为超级构造函数是在自己的构造函数之前调用的:
class Child : Parent { constructor(): super({}) { 5.print() } fun f() { 5.print() } val g: (Int) -> Unit = { it.print() } }
在你的例子中,所讨论的lambda不是Parent
的字段(严格来说),而是一个函数(类构造函数)的参数。
在创建任何对象Child
或Parent
之前构造(解析)lambda。 这就是为什么可以解决方法,并且lambda不在Child
的范围内。
PS
这个话题的名字暗示着下面的情况,但是它编译得很好:
class Child : Parent({}) { val lambdaField: Int.() -> Any = { print() this.print() 5.print() } }