Kotlin:子类如何在超级构造函数调用中使用父类的扩展函数?

时间:2016-05-10 07:00:14

标签: parent-child subclass extension-methods 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
})

2 个答案:

答案 0 :(得分:3)

您无法在Parent 超级构造函数调用参数中使用Child扩展名的原因是其Parent部分尚未初始化在那时,因此不能用作扩展的调度接收器

Member extension functions可以使用eclosing类'成员,这意味着他们需要一个要调用的类的实例,并且不能在自己的构造函数参数中使用该实例。

否则,您可以在Parent成员和构造函数(或Child块)内的任何位置使用init扩展,因为超级构造函数在自己的构造函数之前调用:

class Child : Parent {
    constructor(): super({}) {
        5.print()
    }

    fun f() {
        5.print()
    }

    val g: (Int) -> Unit = { it.print() }
}

答案 1 :(得分:2)

在您的示例中,有问题的lambda不是Parent(严格来说)的字段,而是函数的参数(类构造函数)。

在创建任何对象ChildParent之前构造(解析)lambda。这就是为什么可以解决方法并且lambda不在Child范围内的原因。

PS

主题的名称暗示了以下情况,但它可以编译:

class Child : Parent({}) {
    val lambdaField: Int.() -> Any =  {
        print()
        this.print()
        5.print()
    }
}