I'm learning Scala and there is a thing that I can't find out about the language:
Some time ago I was very comfortable programming in Lisaac, and in Lisaac I could write a class PERSON
with a slot list:ARRAY[SELF]
, which was equivalent to have list:ARRAY[PERSON]
, since SELF
is the type of the object where that slot is.
But by using SELF
, if I write a second class STUDENT
that inherits from PERSON
, then STUDENT
would inherit that slot changing SELF
for STUDENT
, so STUDENT
would have a list of STUDENT
instead of PERSON
.
Can that be done in Scala? I can´t find out anything about that.
Thanks!
There is an idiom for this, and it is used extensively in the collections framework (in all the *Like classes, e.g TraversableLike). You need to add the self-type as a type parameter (like possible in C++ with the CRTP) of the superclass:
trait Person[+Self] {
this: Self => //Declare that any concrete subclass must implement Self; therefore, this can be used with type Self.
//val list: Array[Self] //Not sure that this will work so easily, for the same reason new T[] does not work in Java.
val list = Seq[Self]() //No problem here; Array is really special.
}
After defining this class, we can try defining subclasses in the interpreter:
scala> class Student extends Person[Student]
defined class Student
scala> (new Student).list
res0: Seq[Student] = List() //Note the result type
scala> class Student2 extends Person[Student] //Note the mistake
<console>:9: error: illegal inheritance;
self-type Student2 does not conform to Person[Student]'s selftype Person[Student] with Student
class Student2 extends Person[Student]
A mistake which is not prevented is having this definition, where Self is not redefined:
scala> class SpecStudent extends Student
defined class SpecStudent
Thanks to the +
in front of Self
, which makes it a covariant type parameter (I'm not explaining what that is), this however is at least possible:
scala> class SpecStudentCorrect extends Student with Person[SpecStudentCorrect]
scala> (new SpecStudentCorrect).list
(new SpecStudentCorrect).list
res1: Seq[SpecStudentCorrect] = List()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With