¿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

Respuestas a la pregunta(1)

Su respuesta a la pregunta