¿Por qué usar Val simple en clases no finales?
Si la clase no es la final, puede extenderse.
Hay dos posibilidades para los valores: puede ser anulado y debe ser perezoso, no puede ser anulado y debería ser definitivo.
Si val es final, puede suponer que todos los cálculos sobre él funcionarán a través de la jerarquía de clases. Si se puede anular el valor de val, debe declararlo perezoso para no romperse después de la extensión. Puede dejar val llano y esto no da garantías de que se extendería de manera correcta.
¿Qué casos de uso implican usar valores simples?
Ejemplo de fallo de inicialización de clase sin valores perezosos
abstract class A {
lazy val x1 : String = throw new Exception()
val x2 : String = "mom"
val x3 : String = x1 + ", " + x2
println("A: " + x3)
}
class B extends A {
override lazy val x1: String = "hello"
println("B: " + x3)
}
class C extends B {
override val x2: String = "dad"
println("C: " + x3)
}
probandolo
scala> new B
A: hello, mom
B: hello, mom
res8: B = B@7e2bd615
funciona, pero una subclase adicional rompió la funcionalidad ya existente
scala> new C
A: hello, null
B: hello, null
C: hello, null
res5: C = C@52a53948
establecer perezoso en x2 arregla el caso:
abstract class A {
lazy val x1 : String = throw new Exception()
lazy val x2 : String = "mom"
val x3 : String = x1 + ", " + x2
println("A: " + x3)
}
class B extends A {
override lazy val x1: String = "hello"
println("B: " + x3)
}
class C extends B {
override lazy val x2: String = "dad"
println("C: " + x3)
}
orden de inicialización correcto:
scala> new C
A: hello, dad
B: hello, dad
C: hello, dad
res6: C = C@5e970110