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)?
对于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派生类字段名称的方法?.