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

soc*_*soc 7 inheritance constructor scala field language-design

考虑一下这个简单的Scala类:

class A(val d: Int)
Run Code Online (Sandbox Code Playgroud)

Scala(行为或生成的字节码)之间是否存在差异?

class B(d: Int) extends A(d)
Run Code Online (Sandbox Code Playgroud)

class B(override val d: Int) extends A(d)
Run Code Online (Sandbox Code Playgroud)

或者都是等价的?如果它们不同,那么它们的具体用例是什么?

如果A被定义为是不同的class A(var d: Int)

Aar*_*rup 9

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

对于增值经销商,有一个行为差异.如果没有覆盖,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
Run Code Online (Sandbox Code Playgroud)

这个问题是相关的:惯用Scala处理基类vs派生类字段名称的方法?.