2010-02-24 187 views
8

試圖定義爲默認的構造參數的存取方法,即:如何定義默認構造函數參數的存取方法?

class Person (age: Int) { 
    def age: Int = this.age 
} 

這顯然會導致編譯錯誤:曖昧參照重載定義,在類型=> int和值的類人既方法年齡年齡段類型Int類型匹配預期類型Int

在此上下文中是否有方法來區分成員方法名稱和自動生成的成員值名稱?

當然可以更改任一標識符的名稱,但是在這種情況下是否有一種方法可以實際指定哪個標識符被引用?

回答

16

只需在要作爲實例屬性公開的構造函數參數前加上「val」即可。

+0

謝謝!只是自己想清楚了。:-)但是如果我想覆蓋默認訪問器呢?我想我仍然需要重命名參數? – 2010-02-24 16:01:37

+3

是的,你需要重命名參數(例如'age0'),然後定義訪問器'def age = {Math.abs(age0)' – retronym 2010-02-24 17:33:47

6

使用

class Person (val age: Int) 

,如果你只是想要一個getter或

class Person (var age: Int) 

,如果你也希望有一個二傳手。

3

上面的答案對於統一訪問原則來說非常重要。如果您有或需要Java樣式獲取器和設置器,則還可以使用BeanProperty註釋。

class Person(@scala.reflect.BeanProperty var age: Int) 

這將導致以下方法創建:

def getAge: Int = age 
def setAge(age: Int) = this.age = age 

如果改用爲的BeanProperty如果val而不是變種,二傳手不會被創建,只有吸氣。

另外一個警告,setter方法不能從Scala內部調用。相反,您應該使用統一訪問的標準Scala約定來設置值。

1

爲了保持完整性並擴展以前的答案,還有涵蓋here的技術。

總之,我總是有一個不變的值開始:

class Person (val age: Int) 

然後,如果你計算出你需要的變異值(或者你知道它之前),切換到:

class Person (var age: Int) 

然後,如果你需要驗證或者做得到一些其他的計算或設置,重命名變量,構建模仿原來的命名存取,無需重構代碼的其餘部分:

class Person(var _age: Int) 
{ 
    def age = 
    { 
     println("age requested") 
     _age 
    } 
    def age_=(newAge: Int) = 
    { 
     assert(newAge > 0) 
     println(s"age changed from ${_age} to $newAge") 
     _age = newAge 
    } 
} 

當然,如果你不需要操作,你可以簡化setter或getter。

對所有其他答案的榮譽,這確實是正確的,並且來得早。

相關問題