Dam*_*ian 13 inheritance scala
我正在学习Scala,有一件事我无法找到该语言:
前段时间我在Lisaac编程非常舒服,在Lisaac中,我可以编写一个PERSON带有插槽的类list:ARRAY[SELF],这相当于有list:ARRAY[PERSON],因为SELF是该插槽的对象类型.
但是,通过使用SELF,如果我写的第二类STUDENT,从继承PERSON,然后STUDENT将继承该槽改变SELF了STUDENT,所以STUDENT就会有一个列表STUDENT,而不是PERSON.
可以在Scala中完成吗?我无法找到任何相关信息.
谢谢!
Bla*_*ade 15
这有一个习惯用法,它在集合框架中广泛使用(在所有*Like类中,例如TraversableLike).您需要将self-type添加为超类的类型参数(如C++中可能与CRTP一样):
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.
}
Run Code Online (Sandbox Code Playgroud)
在定义了这个类之后,我们可以尝试在解释器中定义子类:
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]
Run Code Online (Sandbox Code Playgroud)
一个没有阻止的错误就是有了这个定义,其中Self没有被重新定义:
scala> class SpecStudent extends Student
defined class SpecStudent
Run Code Online (Sandbox Code Playgroud)
感谢+前面的Self,这使得它成为一个协变类型参数(我不解释它是什么),但这至少是可能的:
scala> class SpecStudentCorrect extends Student with Person[SpecStudentCorrect]
scala> (new SpecStudentCorrect).list
(new SpecStudentCorrect).list
res1: Seq[SpecStudentCorrect] = List()
Run Code Online (Sandbox Code Playgroud)
我不确定这对你是否真的有用,但我能想到的最接近的是this.type.例如:
scala> class A { val l: List[this.type] = Nil }
defined class A
scala> new A().l
res3: List[A] = List()
scala> class B extends A
defined class B
scala> new B().l
res4: List[B] = List()
Run Code Online (Sandbox Code Playgroud)