2011-07-11 7 views
7

Rozważmy prostą klasę Scala:Różnice podczas zastępowania odziedziczonych pól konstruktora?

class A(val d: Int) 

Czy istnieje różnica w Scala (zarówno w zachowaniu lub wygenerowanego kodu bajtowego) pomiędzy

class B(d: Int) extends A(d) 

i

class B(override val d: Int) extends A(d) 

lub oba równoważne? Jeśli są różne, jaki byłby konkretny przypadek użycia dla każdego z nich?

Czy byłoby inaczej, gdyby A zdefiniowano jako class A(var d: Int)?

Odpowiedz

9

Dla vals nie ma różnicy semantycznej. Jednakże, może występować różnica w wygenerowanym kodzie ttowym. W szczególności, jeśli metoda zdefiniowana w klasie pochodnej odnosi się do d, odnosi się ona raczej do parametru konstruktora d niż do val o tej samej nazwie. Jest to realizowane za pośrednictwem dodatkowego pola prywatnego wygenerowanego dla klasy pochodnej.

Dla zmiennych, istnieje jest a Różnica w zachowaniu. Bez nadpisania wszelkie metody odwołujące się do klasy pochodnej będą odwoływać się do parametru konstruktora, podczas gdy wywołujący odwołanie do obiektu d spoza klasy otrzymają to pole. W takim przypadku dwie wartości mogą się różnić (jeśli wartość zmieniła się od czasu budowy).

Oto sesja, która demonstruje zachowanie z var:

scala> class A(var d: Int) 
defined class A 

scala> class B(d: Int) extends A(d) { override def toString = "d: " + d } 
defined class B 

scala> val b = new B(1) 
b: B = d: 1 

scala> b.d = 2 

scala> b.d 
res1: Int = 2 

scala> b 
res2: B = d: 1 

To pytanie jest związane: Idiomatic Scala way to deal with base vs derived class field names?.