You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在父类构造函数执行前初始化子类重写的属性?

解决Kotlin父类init块执行时子类重写属性未初始化的问题

先还原问题对应的示例代码:

open class Base {
    open val defaultPrefix: String? = null
    val word: String

    init {
        word = "$defaultPrefix ipsum"
    }
}

class ClassA : Base() {
    override val defaultPrefix: String = "foobar"
}

fun main() {
    println(ClassA().word) // 输出:null ipsum
}

问题根源是Kotlin的初始化顺序:父类init块执行早于子类属性初始化,导致父类初始化时子类重写的属性还处于默认值(null)状态。以下是几种可行的解决方案:

方案1:通过父类构造函数传递参数(最推荐)

将需要在父类初始化阶段使用的属性,作为父类构造函数的参数传入,确保父类init块执行前参数已被子类传入并赋值,从根源规避初始化顺序问题。

修改后的最简代码:

open class Base(open val defaultPrefix: String?) {
    val word: String

    init {
        word = "${defaultPrefix ?: ""} ipsum"
    }
}

class ClassA : Base("foobar")

fun main() {
    println(ClassA().word) // 输出:foobar ipsum
}

如果子类需要单独维护defaultPrefix属性,也可以显式重写:

open class Base(prefix: String?) {
    val defaultPrefix: String? = prefix
    val word: String

    init {
        word = "${defaultPrefix ?: ""} ipsum"
    }
}

class ClassA : Base("foobar") {
    override val defaultPrefix: String = "foobar"
}

方案2:使用lazy延迟初始化父类的依赖属性

让父类的word延迟初始化,直到子类属性完成赋值后再计算值,避开父类init块的执行时机限制。

代码示例:

open class Base {
    open val defaultPrefix: String? = null
    val word: String by lazy {
        "${defaultPrefix ?: ""} ipsum"
    }
}

class ClassA : Base() {
    override val defaultPrefix: String = "foobar"
}

fun main() {
    println(ClassA().word) // 输出:foobar ipsum
}

注意:此方案会让word变为延迟加载属性,第一次访问时才会计算值,若需要属性在实例化时就完成初始化,该方案不适用。

方案3:用open函数替代open属性

将defaultPrefix改为open函数,Kotlin中函数的重写遵循动态绑定,父类init块调用函数时会直接调用子类的实现,此时子类函数可以返回正确的值。

代码示例:

open class Base {
    open fun getDefaultPrefix(): String? = null
    val word: String

    init {
        word = "${getDefaultPrefix() ?: ""} ipsum"
    }
}

class ClassA : Base() {
    override fun getDefaultPrefix(): String = "foobar"
}

fun main() {
    println(ClassA().word) // 输出:foobar ipsum
}

内容的提问来源于stack exchange,提问作者Eydamos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 20:20:22