重写继承的构造函数字段时的差异?
考虑这个简单的 Scala 类:
class A(val d: Int)
之间是否存在差异(无论是行为还是生成的字节码)
class B(d: Int) extends A(d)
Scala 中和
class B(override val d: Int) extends A(d)
或两者等价 ?如果它们不同,那么它们各自的具体用例是什么?
如果A
被定义为class A(var d: Int)
会有不同吗?
Consider this simple Scala class:
class A(val d: Int)
Is there a difference in Scala (either in behaviour or generated bytecode) between
class B(d: Int) extends A(d)
and
class B(override val d: Int) extends A(d)
or are both equivalent? If they are different, what would be the specific usecase for each of them?
Would it be different if A
was defined as class A(var d: Int)
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
对于 vals,没有语义差异。但是,生成的字节码可能有所不同。特别是,如果派生类中定义的方法引用
d
,则它引用的是构造函数参数d
,而不是引用的val
同名。这是通过为派生类生成的附加私有字段来实现的。对于 var, 存在行为差异。如果没有重写,任何从派生类内部引用
d
的方法都将引用构造函数参数,而从类外部引用d
的调用者将获取该字段。在这种情况下,两个值可能不同(如果该值自构建以来已发生变化)。这是一个演示 var 行为的会话:
这个问题是相关的: 处理基类字段名称与派生类字段名称的惯用 Scala 方法?。
For vals, there is no semantic difference. However, there may be a difference in the generated bytecode. In particular, if a method defined in the derived class refers to
d
, it refers to the constructor parameterd
rather than to theval
of the same name. This is implemented via an additional private field generated for the derived class.For vars, there is a difference in behavior. Without an override, any methods that refer to
d
from within the derived class will be referring to the constructor parameter, while callers referencingd
from outside the class will get the field. In this case, the two values may differ (if the value has changed since construction).Here's a session that demonstrates the behavior with a var:
This question is related: Idiomatic Scala way to deal with base vs derived class field names?.