我在Scala中有一个A类,就像这个:
class A {
val a = 3
lazy val b = 2
println("a = " + a)
println("b = " + b)
}
Run Code Online (Sandbox Code Playgroud)
接下来,我将这个类扩展到另一个B类:
class B extends A {
override val a = 4
override lazy val b = 3
}
Run Code Online (Sandbox Code Playgroud)
现在,当我创建一个对象时class B,我得到以下输出:
a = 0 //the default value of int is zero `0` in Scala
b = 3
Run Code Online (Sandbox Code Playgroud)
而我期望输出为:
a = 3
b = 2
Run Code Online (Sandbox Code Playgroud)
我的问题是如何知道println()函数中class A定义的值class B,但仅限于b和不是a?
docs.scala-lang.org - tutorials - initialization-order提供了完整的解释.
为了看清楚,让我们在课堂上B和课堂上打印相同的东西A:
class A {
val a = 3
lazy val b = 2
println("A: a = " + a)
println("A: b = " + b)
}
class B extends A {
override val a = 4
override lazy val b = 3
println("B: a = " + a)
println("B: b = " + b)
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,new B()产生:
A: a = 0
A: b = 3
B: a = 4
B: b = 3
Run Code Online (Sandbox Code Playgroud)
非延迟val变量的初始化顺序由下式给出:
在没有"早期定义"(见下文)的情况下,严格的val的初始化按以下顺序进行.
- 超类在子类之前完全初始化.
- 否则,按声明顺序.
因此A在之前完全初始化B.
但val不能多次初始化.因此,当首先处理超类时,Scala内部为它提供了一个默认值(0对于a Int,nullfor String,...)A.
因此,它0首先打印(初始化时A)然后4(初始化时B).
使用lazy vals是scaladoc提出的绕过此限制的解决方案.
| 归档时间: |
|
| 查看次数: |
352 次 |
| 最近记录: |