我有一个 TextElement 类,其类级别变量为
textGravity
,正在使用默认值 Element.HorizontalGravity.DEFAULT
进行初始化
在
TextElement
的构造函数中,我调用父类Element
的超级构造函数,并且在该构造函数中,textGravity
变量获得了他的值。我知道这不是一个好的做法,但它是一个具有此类结构的继承项目,由于我无法在此处解释更复杂的参数,因此目前无法更改。
问题是,在父
textGravity
类的父decode
方法中设置Element
之后...设置的值正在丢失,因为由于某种我不明白的原因,被重置为默认值,因为在超级构造函数之后再次调用子 TextElement 类的这一行:
var textGravity = Element.HorizontalGravity.DEFAULT
为什么会发生这种情况?这怎么可能?我怎样才能避免这种情况?
class TextElement : Element {
var textGravity = Element.HorizontalGravity.DEFAULT
constructor(binaryReader: BinaryReader) : super(binaryReader) {
decode(binaryReader)
}
}
open class Element {
constructor(reader: BinaryReader) {
this.decode(reader)
}
private fun decode(reader: BinaryReader) {
if (this is TextElement) {
(this as TextElement).textGravity = Element.HorizontalGravity.MIDDLE
}
}
}
超类的构造函数将在子类中的属性初始值设定项之前被调用。这是不可避免的。例如,它允许这些属性初始值设定项在超类上可靠地调用函数。
根据您的评论,您切换到
lateinit var
并摆脱了子类自己的属性初始值设定项。这需要满足以下两件事之一:
超类always设置该属性。在你的问题中确实如此,但我认为真正的代码比这更复杂。 😀
或者,您需要使用诸如
::textGravity.isInitialized
之类的东西来保护对该属性的使用,因此如果您尚未初始化它,则不要尝试使用它。例如,我认为您可以在属性声明/初始化程序之后有一个 init
块,它会仔细检查属性是否已初始化,如果没有初始化,则对其进行初始化。
正如您在问题中指出的那样,这段代码总体来说有点可怕,您被困住了。将来阅读这个问题的其他人(👋🏻)可能会尝试重新处理问题,以便超类不会尝试以这种方式弄乱超类构造函数中的子类属性。