为什么被覆盖的变量在 Scala 中得到错误的值? [英] Why do overridden variables get the wrong values in Scala?
问题描述
我在 Scala 中有一个 A 类,就像这个:
I have a class A in Scala, like this one:
class A {
val a = 3
lazy val b = 2
println("a = " + a)
println("b = " + b)
}
接下来,我将这个类扩展到另一个类 B:
Next, I extend this class to another class B:
class B extends A {
override val a = 4
override lazy val b = 3
}
现在,当我创建一个 class B
的对象时,我得到以下输出:
Now, when I create an object of class B
, I get the following output:
a = 0 //the default value of int is zero `0` in Scala
b = 3
而我期望输出是:
a = 3
b = 2
我的问题是 class A
中的 println()
函数如何知道 class B
中定义的值,但只有b
而不是 a
?
My question is how do the println()
functions in class A
come to know about the values defined in class B
, but only of b
and not of a
?
推荐答案
docs.scala-lang.org - 教程 - 初始化顺序 提供了完整的解释.
为了看得更清楚,让我们在 B
类中打印与 A
类中相同的内容:
In order to see clearer, let's print the same thing in class B
as in class 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)
}
在这种情况下,new B()
产生:
In this case, new B()
produces:
A: a = 0
A: b = 3
B: a = 4
B: b = 3
<小时>
非惰性val
变量的初始化顺序为:
在没有早期定义"(见下文)的情况下,初始化严格的 vals 按以下顺序完成.
In the absence of "early definitions" (see below), initialization of strict vals is done in the following order.
- 超类在子类之前完全初始化.
- 否则,按声明顺序.
因此 A
在 B
之前完全初始化.
Thus A
is fully initialized before B
.
但是 val
不能被初始化多次.所以在内部Scala给它一个默认值(0
对于Int
,null
对于String
,..)当首先处理超类 A
时.
But val
can't be initialized more than once. So internally Scala gives it a default value (0
for an Int
, null
for a String
, ..) when dealing first with the superclass A
.
因此它首先打印0
(初始化A
时)然后4
(初始化B
时).
Thus it prints 0
at first (when initializing A
) and then 4
(when initializing B
).
使用惰性 vals 是 scaladoc 绕过这个限制.
Using lazy vals is the solution proposed by the scaladoc to bypass this limitation.
这篇关于为什么被覆盖的变量在 Scala 中得到错误的值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!