Scala之 协变、逆变和不变

基本介绍

  1. Scala的协变(+),逆变(-),协变covariant、逆变contravariant、不可变invariant
  2. 对于一个带类型参数的类型,比如 List[T],如果对 A 及其子类型 B,满足 List[B]也符合 List[A] 的子类型,那么就称为 covariance(协变) ,如果 List[A]是 List[B]的子类型,即与原来的父子关系正相 反,则称为 contravariance(逆变)。如果一个类型支持协变或逆变,则称这个类型为 variance(翻译为可变的或变型),否则称为 invariance(不可变的)
  3. 在 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
  }
}
发布了125 篇原创文章 · 获赞 236 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_33709508/article/details/103659503