我有这个具体的课程:
class Person (var name: String, var surname: String)
我想创建另一个扩展Person的类:
class Son (name: String, surname: String) extends Person(name, surname)
行。 但我确实希望Son的构造函数中的字段必须是var而不是val。 我该如何解决?这些字段必须保留构造函数参数。
更新#2
我的问题如下: 如果我在Son中定义一个方法,如果我将值更改为Son实例的参数,则不起作用。
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 :(得分:11)
如果我理解正确,您希望name
中的surname
和Son
字段是不可变的,而不是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覆盖var - 而且很明显为什么 - subclasses can only override or add functionality to a superclass。如果我们允许vals覆盖变量,我们将从父类中删除重写字段的setter。这打破了继承所暗示的“is-a”关系。
你能做的就是这样实现:
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
现在是一种特质 - 它只是提供了获取name
或surname
的方法。 Son
使用val覆盖Person
- 因此您可以保证任何人都不会再次更改Son
中的字段。
从您的示例中我假设您仍然希望有一种可以修改的Person
类型。你可以使用上面的MutablePerson
类来做到这一点,它允许它的字段被改变。
希望这有帮助!
答案 1 :(得分:6)
你必须将params命名为不同,因为否则son的主体中的方法将尝试访问params而不是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")
}
}