有没有办法确保从基类继承的子类的每个实例都调用一个函数?

问题描述 投票:0回答:1

OptionsAndAnswer
是基类。

abstract class OptionsAndAnswer(
    ...,
    open val options: List<Option>
){
    fun validate() {
        require(options.map { it.id }.distinct().size == options.size) {
            "all option ids should be unique"
        }
    }
}

validate
方法在其子类
init
方法中显式调用,即

data class StringOptionsAndAnswer(
    ...,
    override val options: List<StringOption>
): OptionsAndAnswer(answerId, options) {
    init { validate() }
}

有没有办法调用基类

validate
中的
OptionsAndAnswer
方法,以便所有子类都继承该验证?

将逻辑放入
OptionsAndAnswer
init
方法中会产生
NullPointerException
,因为
OptionsAndAnswer.init
StringOptionsAndAnswer.init
之前被调用。

kotlin abstract-class subclass callstack
1个回答
0
投票

如果您的目标是避免在每个子类中编写

init { validate() }
,您可以在超类中将
options
抽象化,并更改主构造函数以采用简单参数而不是
val

abstract class OptionsAndAnswer(
    options: List<Option>
) {
    abstract val options: List<Option>
    init {
        validate(options)
    }

    private fun validate(options: List<Option>) { ... }
}
data class StringOptionsAndAnswer(
    override val options: List<StringOption>
): OptionsAndAnswer(options)

这样,您可以将

validate
argument 传递到构造函数中,而不是 open 属性。

当然,可以通过以下操作简单地绕过此验证:

data class EvilOptionsAndAnswer(
    override val options: List<Option>
): OptionsAndAnswer(listOf())

因此,如果您的目标是执行此验证,那么这是行不通的。

© www.soinside.com 2019 - 2024. All rights reserved.