2011-07-11 17 views
7

considerar esta clase simple Scala:Diferencias al anular campos de constructor heredados?

class A(val d: Int) 

¿Hay una diferencia en la Scala (ya sea en la conducta o código de bytes generada) entre

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

y

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

o son tanto equivalente? Si son diferentes, ¿cuál sería el uso específico para cada uno de ellos?

¿Sería diferente si A se definió como class A(var d: Int)?

Respuesta

9

Para vals, no hay diferencia semántica. Sin embargo, puede haber una diferencia en el bytecode generado. En particular, si un método definido en la clase derivada se refiere a d, se refiere al parámetro de constructor d en lugar del val del mismo nombre. Esto se implementa a través de un campo privado adicional generado para la clase derivada.

Para vars, hay es a diferencia en el comportamiento. Sin una anulación, cualquier método que haga referencia a d desde la clase derivada se referirá al parámetro constructor, mientras que los llamadores que hacen referencia a d desde fuera de la clase obtendrán el campo. En este caso, los dos valores pueden diferir (si el valor ha cambiado desde la construcción).

Aquí es una sesión que muestra el comportamiento con una 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 

Esta pregunta se relaciona: Idiomatic Scala way to deal with base vs derived class field names?.

Cuestiones relacionadas