开发者学堂课程【Scala 核心编程 - 进阶:协变逆变和不变】学习笔记,与课程紧密连接,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/610/detail/9159
协变逆变和不变
基本介绍
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<String> 并不是 List<Object> 的子类型。而 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]没有从属关系。称为不变。
代码:
val t:Temp[Super]=new Temp[Sub]("hello world1")
class Temp3[A](title:String){//Temp3[+A]7//Temp[-A]
override def toString:String={
title
}}
//支持协变 class Super
class Sub extends Super
写一段代码命名为covariantcontravariant引用上方代码
class Super//父类
//Sub是Super的子类
//不变
class Temp3[A](title: String){//Temp3[+A] //Temp[-A]
override def tostring: String ={
title
}
}
不变的特性
指定代码 va1 t1:Temp3[Sub]=new Temp3[Sub](“hello”);//ok
因为 Temp3[Sub] 不变,Temp3[Sub] 与 Temp3[Sub] 的类型是相同的,没有任何影响。
va1 t2:Temp3[Sub]=new Temp3[Super](“hello”);//error
va1 t3:Temp3[Super]=new Temp3[Sub](“hello”);//error
因为不变所以 Temp3[Super] 与 Temp3[Sub] 没有任何关系。
2.//协变
class Temp4[+A](title: String){//Temp3[+A] //Temp[-A]
override def tostring: String ={
title
}
}
协变的特性
va1 t4:Temp3[Sub]=new Temp3[Sub](“hello”);//ok
Temp3[Sub] 与 Temp3[Sub] 的类型是相同的,没有任何影响。
va1 t5:Temp4[Super]=new Temp4[Sub](“hello”);//ok
va1 t6:Temp4[Sub]=new Temp4[Super](“hello”);//error
支持协变,意味着 Sub 是 Super 的子类那么泛型也支持Sub是Super的子类。Sub 与 Super 相反则错误。
3.//逆变
class Temp5[-A](title: String){//Temp3[+A] //Temp[-A]
override def tostring: String ={
title
}
}
逆变的特性
va1 t7:Temp5[Sub]=new Temp4[Sub](“hello”);//ok
Temp5[Sub] 与 Temp5[Sub] 的类型是相同的,没有任何影响。
va1 t8:Temp5[Sub]=new Temp4[Super](“hello”);//ok
va1 t9:Temp5[Super]=new Temp4[Sub](“hello”);//error
Sub是Super的子类,因为发生逆变则相反。