如果课程不是最终课程,则可以延长课程。
值有两种可能性:它可能被覆盖并且应该是惰性的,它可能不会被覆盖并且应该是最终的。
如果 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