Scala 2.8:如何初始化子类

时间:2011-04-22 13:32:14

标签: scala scala-2.8

请考虑以下代码:

abstract class X {
  def a:Unit
  a
}

class Y extends X {
  var s:String = "Hello"
  def a:Unit = println ("String is "+s)
}

这给出了以下输出:

scala> new Y
String is null
res6: Y = Y@18aeabe

如何在调用X

时让父类s等待a初始化

1 个答案:

答案 0 :(得分:6)

父项的字段和父构造函数始终初始化并在子项的字段和构造函数之前运行。这意味着对a的调用发生在子类中设置var s之前。

通常,从构造函数调用虚方法是个坏主意; C ++甚至不允许它(或者,而不是禁止它,在从超类的构造函数调用时不调用子类中实现的方法)。

但是,如果您将var s中的class Y转换为lazy valdef,则可以解决此问题。 lazy val在第一次访问其值时被初始化,无论是谁; def不存在varval等初始化问题。但是,请注意不要在a的实现中调用任何其他未初始化的结构,因为同样的问题将再次出现。

修改

您还可以使用Scala的“早期定义”(或早期初始化)功能:

class Y extends {
  var s = "Hello"
} with X {
  def a: Unit = println ("String is "+s)
}