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
之前被调用。
如果您的目标是避免在每个子类中编写
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())
因此,如果您的目标是执行此验证,那么这是行不通的。