open class Base {
open val value: String = "Base class"
init {
println("Base class initialized: $value")
}
}
class Derived: Base() {
override val value: String = "Derived class"
init {
println("Derived class initialized: $value")
}
}
fun main() {
val derived = Derived()
}
运行选定的代码时,输出如下:
Base class initialized: null
Derived class initialized: Derived class
我们的疑问就是这个 null,为啥
首选我们要确定一件事情,子类初始化,先会初始化父类。
在 Base 类的 init 块中,value 属性被访问。
由于 Derived 类覆盖了 value 属性,并且 Derived 的 value 尚未初始化(因为 Base 的初始化先于 Derived),此时 value 的值为 null。
Derived 类的初始化顺序:
Derived 的 value 属性被初始化为 "Derived class"。
然后执行 Derived 的 init 块,打印 "Derived class initialized: Derived class"。
其实这里有个警告的 Accessing non-final property value in constructor ,建议我们去掉 open,使value 变成 final 属性不可被子类重写,从而避免警告。这样也不会输出 null。
所以大家要重视警告,避免不必要的异常。
避免在构造函数或init块中调用可被重写的方法
使用final保护关键方法