Kotlin构造函数调用非final函数:抽象函数调用为何结果不符?
解决Kotlin构造函数中调用非final函数的初始化问题
这个问题太典型了——父类构造过程中调用了子类重写的抽象方法,此时子类的成员变量还没完成初始化,自然会拿到类型默认值(比如你例子里的Int默认值0)。这里给你两个最实用的解决思路:
1. 用lazy委托延迟初始化父类属性
把父类里直接调用calculate()的属性改成延迟初始化,这样calculate()会等到第一次访问属性的时候才执行,这时候子类已经完成所有初始化步骤了,能正确拿到x的值:
abstract class Base { // 用lazy委托,第一次访问code时才调用calculate val code by lazy { calculate() } abstract fun calculate(): Int } class Derived(private val x: Int) : Base() { override fun calculate(): Int = x } fun main(args: Array<String>) { val i = Derived(42).code // 现在输出42,符合预期 println(i) }
2. 重构父类,通过构造参数接收计算结果
换一种设计思路:父类不再依赖抽象方法初始化属性,而是让子类在构造时直接把计算好的值传递给父类。这种方式从根源上避免了构造阶段的跨类方法调用,初始化顺序完全可控:
// 父类直接通过构造参数接收code的值 abstract class Base(val code: Int) // 子类构造时把x直接传给父类 class Derived(private val x: Int) : Base(x) fun main(args: Array<String>) { val i = Derived(42).code // 输出42 println(i) }
如果你的业务逻辑允许,我更推荐第二种方案,因为它的代码更简洁,也不存在任何初始化顺序的隐患。
内容的提问来源于stack exchange,提问作者rosghub
相关产品推荐
相关产品推荐

