2011-07-11 61 views
7

考慮這個簡單的Scala類:覆蓋繼承的構造函數字段時的差異?

class B(d: Int) extends A(d) 

class B(override val d: Int) extends A(d) 

之間

class A(val d: Int) 

有(行爲或生成的字節碼或者)Scala中的差值或都是相同呢?如果他們不同,那麼每個人的具體用途是什麼?

難道是不同的,如果A被定義爲class A(var d: Int)

回答

9

對於丘壑,不存在語義差別。但是,可能在生成的字節碼中有所不同。特別是,如果在派生類中定義的方法引用d,則它指的是構造函數參數d,而不是同名的val。這是通過爲派生類生成的附加私有字段實現的。

對於變量,有 a 行爲差異。如果沒有覆蓋,從派生類中引用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?