2012-11-30 96 views
4

我有這樣的具體類:斯卡拉:延長混凝土類構造函數的參數

class Person (var name: String, var surname: String) 

,我想創建一個擴展人另一個類:

class Son (name: String, surname: String) extends Person(name, surname) 

確定。 但我確實希望Son的構造函數中的字段必須是var而不是val。 我該如何解決這個問題?這些字段必須保留構造函數參數。

更新#2

我的問題是: 如果我定義兒子的方法,這不,如果我的值更改爲兒子的一個實例的參數工作。

class Son (name: String, surname: String) extends Person(name, surname){ 
    def printSon = { 
    if(this.name=="name")println("Error name Person") 
    if(this.surname=="surname")println("Error surname Person") 
    } 
} 

object main { 
    def main(args: Array[String]): Unit = {} 

    val Marco = new Son("Marco","Bianchi") 
    Marco.printSon // So far everything is ok 
    Marco.name="name" 
    Marco.printSon // Here in control is not done, because Marco.name="name" writes in Person 
    println("FINE") 
} 

兒子姓e的姓氏是val型。

+0

這些字段已經在'兒子'中可變。你的意思可能相反嗎?或者你想實現的是什麼? – Frank

+0

嗨,我在#2更新# – user1826663

+0

回答了你,我沒有看到你通過試圖隱藏Person的構造函數的參數。如果你將Person改爲Trait,那麼你只需將Son與Person一起,就可以訪問它的字段 – Alex

回答

10

如果我理解正確,您希望Son中的namesurname字段是不可變的,而不是Person中的字段,它們是變量。

這根本不可能。做到這一點的唯一方法是通過覆蓋:

class Person (var name: String, var surname: String) 

//this won't compile 
class Son(override val name: String, override val surname: String) extends Person(name, surname) 

在Scala中,不能覆蓋與VAL一個變種 - 這是很明顯的原因 - subclasses can only override or add functionality to a superclass。如果我們穿着val來覆蓋變量,我們會從父類中移除覆蓋字段的setter。這打破了繼承隱含的「是 - 一個」關係。

你可以做的就是實現這個就像這樣:

trait Person { 
    def name: String 
    def surname: String 
} 

//this is fine now 
class Son(val name: String, val surname: String) extends Person 

//in case you want a type of person which can be changed. 
class MutablePerson(var name: String, var surname: String) extends Person 

Person現在是一個特點 - 它只是提供了獲取namesurname的一種方式。 Son通過使用vals覆蓋Person - 因此您可以保證沒有人會再次更改Son中的字段。

從你的例子我假設你仍然想要一個Person類型可以修改。你可以使用上面的MutablePerson類來做到這一點,這允許它的字段發生變化。

希望這會有所幫助!

6

你必須命名參數不同,否則兒子身體中的方法將嘗試訪問參數而不是Person類中的字段。如果您在身體中訪問它們,Scala會自動爲params創建字段。它會工作,當你做這樣的事情(這也是一個常用的模式):

class Son (_name: String, _surname: String) extends Person(_name, _surname){ 
    def printSon = { 
    if(name == "name")println("Error name Person") 
    if(surname == "surname")println("Error surname Person") 
    } 
}