如果课程不是最后一堂课,可能会延长。
值有两种可能性:它可能被覆盖并且应该是惰性的,它可能不会被覆盖并且应该是最终的。
如果 val 是最终的 - 您可以假设对它的所有计算都将通过类层次结构进行。如果 val 可能被覆盖,你应该声明它是惰性的,以免在扩展后被破坏。您可以将 val 保留为普通,但这不能保证它会以正确的方式扩展。
什么用例意味着使用普通值?
没有惰性值的类初始化失败的示例
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)
}
测试它:
scala> new B
A: hello, mom
B: hello, mom
res8: B = B@7e2bd615
它有效,但进一步的子类化破坏了已有的功能
scala> new C
A: hello, null
B: hello, null
C: hello, null
res5: C = C@52a53948
在 x2 上设置懒惰可以修复这种情况:
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)
}
正确的初始化顺序:
scala> new C
A: hello, dad
B: hello, dad
C: hello, dad
res6: C = C@5e970110