Sto vedendo alcune stranezze di inizializzazione quando si mescolano val e def nel mio tratto. La situazione può essere riassunta con il seguente esempio.Ottenere un valore null con un valore val di valore astratto in un tratto
Ho un tratto che fornisce un campo astratto, chiamiamolo fruit
, che dovrebbe essere implementato nelle classi child. Utilizza anche quel campo in val:
scala> class FruitTreeDescriptor(fruit: String) {
| def describe = s"This tree has loads of ${fruit}s"
| }
defined class FruitTreeDescriptor
scala> trait FruitTree {
| def fruit: String
| val descriptor = new FruitTreeDescriptor(fruit)
| }
defined trait FruitTree
Quando sovrascriviamo fruit
con un def
, le cose funzionano come previsto:
scala> object AppleTree extends FruitTree {
| def fruit = "apple"
| }
defined object AppleTree
scala> AppleTree.descriptor.describe
res1: String = This tree has loads of apples
Tuttavia, se sovrascrivo fruit
utilizzando un val
...
scala> object BananaTree extends FruitTree {
| val fruit = "banana"
| }
defined object BananaTree
scala> BananaTree.descriptor.describe
res2: String = This tree has loads of nulls
Cosa sta succedendo qui?