覆盖 Kotlin 中的父初始化块

Override parent init block in Kotlin

提问人:NeoRuss 提问时间:11/15/2023 更新时间:11/15/2023 访问量:55

问:

当我创建子类的实例时,我不希望父类的 init 块打印消息。

例:

fun main() {
    var instance2 = Child()

}

open class Parent() {
    init{
        println("This is a parent object")
    }
    
    
}

class Child: Parent(){
    init{
        println("This is a child object")
    }
}

输出:

This is a parent object // Don't want this
This is a child object

我找到了这样的方法:

fun main() {
    var instance2 = Child()

}

open class Parent() {
    init {
        initMethod()
    }
    
    open fun initMethod(){
        println("This is a parent object")
    }
    
    
}

class Child: Parent(){
    override fun initMethod(){
        println("This is a child object")
    }
    
}

输出:

This is a child object

但这对我来说似乎不合适。initMethod 是开放和公开的,它应该是私有的。

一定有更合法的方法可以做到这一点吗?

Kotlin OOP 初始化

评论

1赞 broot 11/15/2023
是你控制还是第三方代码?我认为你的根本问题是你在构造函数中放了一些代码,这些代码可能不应该在那里。构造函数用于初始化对象,初始化其内部状态,因此我们无法覆盖其行为。您的真实用例是什么?Parent
1赞 Tenfour04 11/15/2023
好点子,我给了它怀疑的好处,但它可能是一个 XY 问题。想要有选择地初始化某些内容的事实是一个危险信号,违反了基本的 OOP 原则。
0赞 NeoRuss 11/15/2023
我会检查我做错了什么,谢谢你的警告。无论如何,@Tenfour4您的回答解决了我的问题。谢谢!

答:

0赞 Tenfour04 11/15/2023 #1

是的,永远不要从构造函数调用打开的函数或属性。

也许你可以用一个受保护的构造函数来做到这一点:

open class Parent protected constructor(runParentInitMethod: Boolean) {

    constructor(): this(true)

    init {
        if (runParentInitMethod) initMethod()
    }
    
    private fun initMethod(){
        println("This is a parent object")
    }
    
}

class Child: Parent(false) {

    init {
        childInitMethod()
    }

    private fun childInitMethod(){
        println("This is a child object")
    }
    
}