重写继承的构造函数字段时的差异?

发布于 2024-11-19 16:17:52 字数 348 浏览 4 评论 0原文

考虑这个简单的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

亣腦蒛氧 2024-11-26 16:17:52

对于 vals,没有语义差异。但是,生成的字节码可能有所不同。特别是,如果派生类中定义的方法引用d,则它引用的是构造函数参数d,而不是引用的val同名。这是通过为派生类生成的附加私有字段来实现的。

对于 var, 存在行为差异。如果没有重写,任何从派生类内部引用 d 的方法都将引用构造函数参数,而从类外部引用 d 的调用者将获取该字段。在这种情况下,两个值可能不同(如果该值自构建以来已发生变化)。

这是一个演示 var 行为的会话:

scala> class A(var d: Int)
defined class A

scala> class B(d: Int) extends A(d) { override def toString = "d: " + d }
defined class B

scala> val b = new B(1)
b: B = d: 1

scala> b.d = 2

scala> b.d
res1: Int = 2

scala> b
res2: B = d: 1

这个问题是相关的: 处理基类字段名称与派生类字段名称的惯用 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 parameter d rather than to the val 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 referencing d 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:

scala> class A(var d: Int)
defined class A

scala> class B(d: Int) extends A(d) { override def toString = "d: " + d }
defined class B

scala> val b = new B(1)
b: B = d: 1

scala> b.d = 2

scala> b.d
res1: Int = 2

scala> b
res2: B = d: 1

This question is related: Idiomatic Scala way to deal with base vs derived class field names?.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文