首页 > 解决方案 > 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

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

有人可以在较低级别解释这里的事件链吗?

标签: scalainheritanceconstructorobject-initialization

解决方案


您可以将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. 返回childValue的是null,因为当父构造函数被调用时,子构造函数还没有被调用。

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


相关答案:

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

  2. require抽象超类中的断言创建 NPE


推荐阅读