考虑这个简单的Scala类:
class A(val d: Int)
在
之间Scala(行为或生成的字节码)是否存在差异class B(d: Int) extends A(d)
和
class B(override val d: Int) extends A(d)
或两者都相同?如果它们不同,那么它们的具体用例是什么?
如果将A
定义为class A(var d: Int)
?
答案 0 :(得分: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
这个问题是相关的:Idiomatic Scala way to deal with base vs derived class field names?。