基本介绍
- Scala的
协变(+
),逆变(-)
,协变covariant、逆变contravariant、不可变invariant
- 对于一个带类型参数的类型,比如 List[T],如果对 A 及其子类型 B,满足 List[B]也符合 List[A] 的子类型,那么就称为 covariance(协变) ,如果 List[A]是 List[B]的子类型,即与原来的父子关系正相 反,则称为 contravariance(逆变)。如果一个类型支持协变或逆变,则称这个类型为 variance(翻译为可变的或变型),否则称为 invariance(不可变的)
- 在 Java 里,泛型类型都是 invariant,比如 List 并不是 List 的子类型。而 scala 支持,可以在定义类型时声明(用加号表示为协变,减号表示逆变),如:
trait List[+T]
在类型定义时声 明为协变这样会把 List[String]作为 List[Any]的子类型。
应用实例
在这里引入关于这个符号的说明,在声明 Scala 的泛型类型时:
“+
”表示协变 C[+T]
:如果 A 是 B 的子类,那么 C[A]是 C[B]的子类
,称为协变
“-
”表示逆变 C[-T]
:如果 A 是 B 的子类,那么 C[B]是 C[A]的子类
,称为逆变
C[T]
:无论 A 和 B 是什么关系,C[A]和 C[B]没有从属关系
。称为不变.
案例演示
//协变
class Temp4[+A](title: String) { //Temp3[+A] //Temp[-A]
override def toString: String = {
title
}
}
//逆变
class Temp5[-A](title: String) { //Temp3[+A] //Temp[-A]
override def toString: String = {
title
}
}
//不变
class Temp3[A](title: String) { //Temp3[+A] //Temp[-A]
override def toString: String = {
title
}
}
//支持协变
class Super //父类
//Sub是Super的子类
class Sub extends Super
测试
object Demo {
def main(args: Array[String]): Unit = {
val t1: Temp3[Sub] = new Temp3[Sub]("hello");
//ok
val t2: Temp3[Sub] = new Temp3[Super]("hello");//error
val t3: Temp3[Super] = new Temp3[Sub]("hello");//error
val t4: Temp3[Sub] = new Temp3[Sub]("hello"); //ok
val t5: Temp4[Super] = new Temp4[Sub]("hello"); //ok
val t6: Temp4[Sub] = new Temp4[Super]("hello"); //ok
val t7: Temp5[Sub] = new Temp5[Sub]("hello"); //ok
val t8: Temp5[Sub] = new Temp5[Super]("hello"); //ok
val t9: Temp5[Super] = new Temp5[Sub]("hello"); //ok
}
}