Kotlin父类B初始化块与构造函数属性值差异问题咨询
问题解析:父类init块与构造函数中属性值差异原因
我无法理解以下代码中,父类B的init{}块里i和s的值分别为0和null,但B的第二个构造函数中这两个值却是200和param2,请帮忙解释原因。
代码示例
class A(override var i: Int, override var s: String) : B(200, "param2","param3") { init { println(i) println(s) } } open class B(open var i: Int, open var s: String) { init { println("class B init") println("i in init B2 is $i") println("s in init B2 is $s") } constructor(i: Int, s: String, s2: String) : this(i, s) { println("second constructor B") println(" i = $i in second constructor") println(" s = $s in second constructor") println(" s2 = $s2 in second constructor") } } fun main() { val ins2 = A(500, "500S") }
运行结果
class B init i in init B2 is 0 s in init B2 is null second constructor B i = 200 in second constructor s = param2 in second constructor s2 = param3 in second constructor 500 500S
原因解释
- 子类A通过
override var重写了父类B的i和s属性,这导致父类中对这两个属性的访问,在子类实例化时会指向子类的对应属性,而非父类自身的属性。 - 实例化A的流程:调用A的构造函数后,会先触发父类B的第二个构造函数,该构造函数通过
: this(i,s)调用父类主构造函数。 - 父类主构造函数执行时会优先运行
init块,但此时子类A的i和s还未完成初始化(子类的属性赋值逻辑在父类初始化完成后才会执行),所以init块中访问的是子类A里被重写属性的默认值:Int类型默认0,String类型默认null。 - 父类的第二个构造函数在
init块执行完毕后才会运行,这里的i和s是构造函数接收的参数值(也就是传入的200和param2),和子类的重写属性无关,所以能正确显示传入的参数内容。 - 父类初始化完成后,子类A的属性才会被赋值为500和"500S",因此A的
init块会输出这两个最终值。
内容的提问来源于stack exchange,提问作者amateur programmer
相关产品推荐
相关产品推荐

