2012-11-30 59 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") 
    } 
}