Scala:运行重写的值父代码,但不在父代码处赋值



运行下面的代码:

class Parent {
val value = {
println("Setting value in parent")
"ParentVal"
}
println(s"Parent value is ${value}")
}
class Child extends Parent {
override val value = {
println("Setting value in child")
"ChildVal"
}
println(s"Child value is ${value}")
}
new Child

生成以下输出:

Setting value in parent
Parent value is null
Setting value in child
Child value is ChildVal

因此,运行与父值赋值关联的代码,但是值并未真正在父值赋值处赋值。之后,子代码运行并按预期分配值。

有人可以在较低的层面上解释这里的事件链吗?

您可以将val视为没有setter的私有成员变量+getter方法的组合。如果你在没有vals 的情况下重写代码,它将是这样的:

class Parent {
private[this] var parentValue = {
println("Setting value in parent")
"ParentVal"
}
def value: String = parentValue
println(s"Parent value is ${value}")
}
class Child extends Parent {
private[this] var childValue = {
println("Setting value in child")
"ChildVal"
}
override def value = childValue
println(s"Child value is ${value}")
}
new Child

就像原版一样,它打印:

Setting value in parent
Parent value is null
Setting value in child
Child value is ChildVal

这是因为父构造函数调用方法value,但此方法被def value = childValue覆盖。返回的childValuenull的,因为当调用父构造函数时,子构造函数尚未被调用。

您可以在此处阅读有关对象初始化顺序的更多信息。


相关答案:

  1. 为什么在 val 表达式中使用 val 和从超类调用实现抽象方法会返回 NullPointerException。

  2. 在抽象超类中使用require断言创建 NPE

相关内容

  • 没有找到相关文章

最新更新