问题
Consider the following code:
abstract class X {
def a:Unit
a
}
class Y extends X {
var s:String = "Hello"
def a:Unit = println ("String is "+s)
}
This gives the following output:
scala> new Y
String is null
res6: Y = Y@18aeabe
How can I get the parent class X
to wait for s
to be initialized when calling a
回答1:
The parent's fields and the parent constructor are always initialized and run before the children's field and constructor. It means that the call to a
happens before your var s
is set in the child class.
In general, it's a bad idea to call a virtual method from a constructor; C++ even disallows it (or, rather than disallowing it, doesn't call the method implemented in the child class when called from the superclass's constructor).
However, you can fix it if you turn your var s
in class Y
into a lazy val
or a def
instead. lazy val
s are initialized the first time their value is accessed, no matter by whom; def
s pose no initialization issues like var
s or val
s. However, be careful not to call any other uninitialized structure from within the implementation of a
, as the same problem will show up again.
Edit:
You can also use Scala's “early definitions” (or early initialization) feature:
class Y extends {
var s = "Hello"
} with X {
def a: Unit = println ("String is "+s)
}
来源:https://stackoverflow.com/questions/5755925/scala-2-8-how-to-initialize-child-class