我正在制作一个kotlin库,它相当于现有的python库 . 用另一种语言生成等价代码可能是一个挑战 .

具体来说,我有一个基类构造函数方法的情况,它使用一个可以在基类中重写的值 .

挑战是在子类中重写的val没有在基类构造函数之前应用的值 . 在python中,子类构造函数中的一些代码可以在调用基类构造函数之前执行,但在kotlin中,基类构造函数的所有代码都首先执行 .

但请考虑这个kotlin代码:

open class Base{
    val simple = 3
    open val open = 3
    open val openGet = 3
    open val getter get()= 3
    open val getOpen get()= 3
    open val getDelg by GetDelg(3)
    init {
        println("base simple $simple open $open openG $openGet "+
                "getOpen $getOpen getter $getter "+
                " getDelg $getDelg")
    }
    //open fun add(a:Int,b:Int) = a + b
}

class SubClass:Base(){
    override val open = 4
    override val openGet get()= 4
    override val getter get() = 4
    override val getOpen = 4
    //override val getDelg by GetDelg(4)  //uncomment for null pointer
    init {
        println("sub simple $simple open $open openG $openGet "+
                "getOpen $getOpen getter $getter "+
                " getDelg $getDelg")

    }
}
class GetDelg(val value:Int){
    operator fun getValue(thisRef: Any?, property: KProperty<*>): Int {
        return value
    }
}

基类init中的Open为0,因为尚未运行设置值的代码(不是3,因为super.open是单独的) .

openG,一个被get()方法覆盖的值,可能会意外地返回两个init()方法中的覆盖值,因此对于许多情况来说这是一种可能的方法,但是在我试图解决的特定情况下不能工作 .

getOpen,由简单初始化覆盖的基础中的get()方法,表现为由新的初始化覆盖的简单初始化值,该初始化将在基本init()方法中被整合

getter(),由另一个get()方法覆盖的get()方法返回覆盖值,就像openG一样

如果在基本init()方法期间调用,则getDelg()实际上会生成空指针异常,因为尚未计算重写值

注意:我假设此行为的一部分基于以下事实:重写的属性实际上是新的不同属性,因此它们不从基类属性继承值,这仍然可以通过超级访问..这意味着,直观地反驳,在base init() 方法,返回0,而子类 init() 中的super.open将返回3

所以问题是,如何使用委托覆盖,但仍然在基类init中访问了覆盖委托?

我目前的想法是将基类中初始化的值移动到惰性属性,但我想有其他想法 .