2012-05-03 43 views
11

一個相當簡單的練習Cay Horstmann的本書«斯卡拉的不耐煩»讓我困惑。這是關於primaryauxiliarydefault primary構造函數:構造函數在斯卡拉(主/輔助/默認主)

前5.10: 考慮類

class Employee(val name: String, var salary: Double) { 
    def this() { this("John Q. Public", 0.0) } 
} 

重寫它使用明確的領域和默認的主構造。

我不確定我應該做什麼。你們中的一些人能否提出解決方案?

然而,試圖解決這個練習可以使我意識到這是我之前關於主構造和val領域還沒有注意到(正如你所看到的,我不是很確定):

上午我如果我說0123'字段(nameEmployee類中)只能通過primary的構造函數初始化,而不是通過auxiliary初始化?在後一種情況下,編譯器會將其視爲重新分配給導致錯誤的val字段。

起初我認爲val字段與java中的final字段大致相當,期望在任何構造函數中第一次分配它們都是合法的,但似乎我錯了。

我不太滿意什麼可能只是一個瘋狂的猜測,所以我很感激,如果有人能給我更準確的信息關於這一點。

+0

我有同樣的練習這個確切的問題。也許我被作者的「明確」含義所困惑。 – vmayer

回答

12

從「在Scala編程,第二版」第6.7段:

在Scala中,每一個輔助的構造函數必須調用同一個類作爲其第一個動作的另一個構造。 這條規則的最終結果是,Scala中的每個構造函數調用最終都會調用該類的主構造函數。主構造函數因此是一個類的單一入口點。

因此所有用於val初始化的數據必須位於主構造函數中。

你有明確的領域類可能是這樣的:

class Employee(n: String = "John Q. Public", s: Double = 0.0) { 
    val name = n 
    var salary = s 
} 

或無默認參數值:

class Employee(n: String, s: Double) { 
    def this() = this("John Q. Public", 0.0) 
    val name = n 
    var salary = s 
} 
+0

謝謝你的回答。我找到了一個與您的解決方案非常接近的解決方案,但認爲它不符合練習的目標,因爲我認爲「缺省主構造函數」是「沒有明確聲明的無參數沉悶構造函數」。 –

11

其實,我腦子裏想的是一個無參數的初級版本構造函數,如下所示:

class Employee { 
    private var _name = "John Q. Public" 
    var salary = 0.0 
    def this(n: String, s: Double) { this(); _name = n; salary = s; } 
    def name = _name  
} 

顯然,這比在t中定義字段差他是主要的構造者,這是我想要做的。

+1

非常感謝您花時間澄清練習的目標。同時也非常感謝你的書,這本書與Martin Odersky的作品完全相輔相成,並且比任何其他有關這個主題的書籍都更加出色,Scala的第一步更簡單,更愉快。 –