2014-10-17 91 views
2

該主題已經討論過,但沒有得到滿意的回答(在我看來)。 考慮下面的Scala代碼:scala覆蓋類參數

class A(a:Int) { val _a=a } 
class A1(val a:Int) { val _a=a } 

class B(a:Int) extends A(a)     // OK 
class C(val a:Int) extends A(a)    // OK 

class B1(a:Int) extends A1(a)     // OK 
class C1(val a:Int) extends A1(a)    // fails 
class D1(override val a:Int) extends A1(a)  // OK 

我認爲,聲明類參數作爲VAL只對構造函數調用的效果: 參數被複制,而不是傳遞引用。然而,在每種情況下,類字段都被分配爲一個val。它是否正確?

現在我不明白的是爲什麼我們需要在最後一行覆蓋關鍵字。 請注意,我們不會將類聲明爲case類,因此不會自動分配字段。

最後是有一個很好的理由,爲什麼一個甚至會想定義像A1類與VAL 類參數?

在此先感謝所有答覆。

回答

4

我認爲,聲明類參數作爲VAL只對構造函數調用的 效果:該參數將被複制,而不是 傳遞引用。然而,在每種情況下,班級字段被分配爲 作爲val。它是否正確?

根本不是。

如果有VAL或VAR在構造函數中,並導致VAL或相同名稱的VAR在類中聲明,並構造參數在建設分配給它。否則,如果構造函數參數在初始化之外使用,即在方法中,則可以在該類中創建(私有)val。

在A1類,成員_a真的是沒用的,因爲如果你寫

class A1(val a: Int) {} 

它相當於

class A1(someFreshName: Int) {val a = someFreshName} 

所以在C1,您要聲明一個新成員,而已經有一個。因此,覆蓋。 在您的特定情況下,這兩個成員將具有相同的價值,但你很可能做的(也許不是一個好主意)

class C1(override val a: Int) extends A1(12) 

然後,新成員a將有構造函數的參數爲​​值,和以前的a將有價值12並被隱藏(但仍然,代碼寫在A1將訪問它)。

+0

迪迪埃:好的,謝謝,這真的讓我們大惑不解。 – 2014-10-17 10:03:45

+0

爲什麼我會在'class A1(val a:Any){def test = a};}中獲得'm:m';類C1(覆蓋VAL一個:任何)延伸A1(12){倍率DEF的toString = S 「$ A:$測試」}; println(新的C1(「m」))'? 「A1會訪問它」是什麼意思? – 2016-01-11 18:54:53