after
in Example
is instantiated right away, before your Ex
actually is instantiated - and then before even looking at your x
.
To fix it you can turn after
into a lazy val
, it will be evaluated the first time you use it.
Frage
I'd like to define a val
in a trait
that gets computed once by sub-class that gets instantiated.
For instance :
trait Example
{
val p : Int
val after : Int = p + 1
}
class Ex(x : Int) extends Example
{
val p = x
}
I want after
to be computed for each instance of Ex, but no matter which parameter x
I give, after
is always 1
. As if, p
was 0
for the computation.
Of course, it works with def, but then it is no longer computed only once.
Lösung
after
in Example
is instantiated right away, before your Ex
actually is instantiated - and then before even looking at your x
.
To fix it you can turn after
into a lazy val
, it will be evaluated the first time you use it.
Andere Tipps
First of all a val
variable is immutable, so it can only be assigned once. So it would not be possible to do p = x
. But when you do val p = x
in the Ex
class you are assigning other variable that you just defined, so after
would not change.
You have to define the abstract variable var p
in your Ex
class, so it will be able to set the val p
defined in Example
. For example, define the var p
in the constructor as below.
trait Example
{
val p : Int
val after : Int = p + 1
}
class Ex(val p : Int) extends Example
Demo
scala> val ex = new Ex(5)
ex: Ex = Ex@1f7ebc89
scala> ex.p
res4: Int = 5
scala> ex.after
res5: Int = 6