我有一个包含抽象方法和主要构造函数的抽象类
abstract class Article constructor(
text: String
) {
var text: String = text
set(value) {
assert(isValid(value))
field = value
}
val isValid: Boolean = isValid(this.text)
abstract fun isValid(text: String): Boolean
}
我还有另一个继承/扩展main的类。
class ShortArticle(
text: String
) : Article(string) {
override fun isValid(text: String) = text.length == 11
}
我需要验证所创建的每篇文章,并且还需要从Article抽象类继承。
但是,如果我要像这样创建子类:
ShortArticle("hello world blahlblahslab")
未调用验证(自定义设置器)。 在这种情况下调用它:
var article = ShortArticle("hello world blahlblahslab")
article.text = "new text that is validated"
我尝试创建在分配过程中验证的函数。
var text:字符串=验证(文本)
但是它作为文本传递给ShortArticle null 。
答案 0 :(得分:2)
以您的方式进行分配时,它不会触发自定义设置器。它与Java类似,只是直接设置它并绕过setter。如果要触发设置器,则需要从init块或构造函数中调用它。但是,由于您仅使用主构造函数,因此我将使用init块。
由于我不了解自己的问题,这是合法的:
abstract class Article constructor(
text: String
) {
var text: String
init { this.text = text }
val isValid: Boolean = isValid(this.text)
abstract fun isValid(text: String): Boolean
}
但这不是:
abstract class Article constructor(
text: String
) {
var text: String
set(value) {
assert(isValid(value))
field = value
}
init { this.text = text }
val isValid: Boolean = isValid(this.text)
abstract fun isValid(text: String): Boolean
}
但是您可以通过声明如下文本来部分解决此问题:
var text: String = ""
set(value) {
assert(isValid(value))
field = value
}
请注意,由于初始化的顺序,init块 处于文本变量的初始化之后,但isValid变量的初始化之前。否则,isValid会离开""
默认值,并且字段本身为false。但是,我没有看到该字段的任何值-您具有isValid
函数,该函数的作用类似于该方法的实时更新版本。如图所示,如果文本字段,isValid字段和init块的顺序是除此以外的任何内容:
var text: String = ...
set(value) { ... }
init { this.text = text; }
val isValid: Boolean = isValid(this.text)
它将失败。 init块之后的text
将无法编译,而init块之前的isValid
将导致使用isValid
而不是""
的实际值进行text
调用
就设计而言,我会选择这样的东西:
abstract class Article constructor(text: String) {
var text: String = "" // required default value to enable initialization in the init block
set(value) {
assert(isValid(value)) // checks the validity
field = value
}
init { this.text = text } // assigns
protected abstract fun isValid(text: String): Boolean
}
由于您设计类的方式,如果无效,它将引发异常。另外,isValid是最终的,这意味着它不会改变,使其毫无意义。我还使isValid
函数受到保护,因为它不是静态函数。除非初始化该类,否则它将无法用于验证,这时无论如何检查都为时已晚。
答案 1 :(得分:1)
您可以向Article
构造函数添加显式设置值。然后将调用验证
abstract class Article constructor(
text: String
) {
var text: String = ""
set(value) {
assert(isValid(value))
field = value
}
init {
this.text = text
}
val isValid: Boolean = isValid(this.text)
abstract fun isValid(text: String): Boolean
}