Scala: Extend concrete class with constructor parameters
Solution 1
If I understand correctly you want the name
and surname
fields in Son
to be immutable, as opposed to those in Person, which are vars.
That simply isn't possible. The only way to do it would be by overwriting:
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)
In Scala you cannot overwrite a var with a val - and it is pretty obvious why - subclasses can only override or add functionality to a superclass. If we wore to allow vals to override vars we would remove from the parent class the setter for the overridden field. This breaks the "is-a" relationship implied by inheritance.
What you could do is implement this like so:
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
now is a trait - it just provides a way of getting the name
or surname
. Son
overrides Person
by using vals - and thus you get the guarantee that nobody will change the fields in Son
ever again.
From your example I assume that you still want to have a type of Person
that can be modified. And you can do that using the MutablePerson
class above, which does allow it's fields to be mutated.
Hope this helps !
Solution 2
You have to name the params different, because otherwise the methods in the body of son will try to access the params and not the fields in the Person
class. Scala will automatically create fields for the params if you access them in the body. It will work, when you do something like this (which also is a commonly used pattern):
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")
}
}
user1826663
Updated on June 09, 2022Comments
-
user1826663 almost 2 years
I have this concrete class:
class Person (var name: String, var surname: String)
and I want to create another class that extends Person:
class Son (name: String, surname: String) extends Person(name, surname)
OK. But I do want the fields in the constructor of Son must be var and not val. How do I fix this? The fields must remain constructor parameters.
UPDATE #2
My problem is as follows: If I define a method in Son, this does not work if I change the value to the parameters of an instance of 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") }
name e surname in Son are of type val.