Scala:已运行重写的父代码,但未在父级分配值 [英] Scala: Overridden value parent code is run but value is not assigned at parent

查看:171
本文介绍了Scala:已运行重写的父代码,但未在父级分配值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

运行以下代码:

  class Parent {
val value = {
println(在父母中设置值)
ParentVal
}
println(s父值为$ {value})
}

class Child extends Parent {
override val value = {
println(child value in child)
ChildVal
}
println(sChild value is $ {值})
}

新孩子

生成这个输出:

 在父级中设置值
父级值为空
在子级中设置值
子值是ChildVal

因此,运行与父值赋值关联的代码,但值不是真的在父母那里分配了。然后子代码运行并按预期分配值。



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

解决方案

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

  class Parent {
private [this] var parentValue = {
println(在父级中设置值)
ParentVal
}
def value: String = parentValue
println(sParent value is $ {value})
}

class Child extends Parent {
private [this] var childValue = {
println(设置孩子的价值)
ChildVal
}
覆盖def值= childValue
println(s子值为$ {value} )
}

新孩子

就像原来的一样,它打印:

 在父级中设置值
父级值为空
在子级中设置值
子值为ChildVal

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

您可以阅读更多关于此处的对象初始化顺序






相关答案:为什么使用val实现抽象方法并在val表达式中从超类调用返回NullPointerException


Running the code below:

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

Produces this output:

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

So the code associated with the parent value assignment is run, however the value is not really assigned at the parent. Afterwards the child code runs and it assigns the value as expected.

Could someone explain the chain of events here at a lower level?

解决方案

You can think about val as if it were a combination of a private member variable without setters + a getter method. If you rewrite your code without vals, it would be something like this:

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

Just as the original, it prints:

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

This is because the parent constructor invokes the method value, but this method is overridden by def value = childValue. The returned childValue is null, because when the parent constructor is invoked, the child constructor has not been invoked yet.

You can read more about object initialization order here.


Related answer: Why does implement abstract method using val and call from superclass in val expression return NullPointerException.

这篇关于Scala:已运行重写的父代码,但未在父级分配值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆