Scala 泛型协变与泛型边界
2019-11-22 本文已影响0人
数星星的鱼
代码准备
class Animal
class Dog extends Animal
class ErHa extends Dog
泛型协变
泛型协变、逆变、不变是指拥有泛型的类在声明和赋值时的对应关系。
协变:声明时泛型是父类,赋值时泛型可以是父类也可以是子类
逆变:声明时泛型是子类,赋值时泛型可以是子类也可以是父类
不变:声明时泛型是什么类型,赋值时也只能是什么类型
代码演示
class MyList1[+V] // 协变类型,泛型前面有一个'加号'
class MyList2[-V] // 逆变类型,泛型前面有一个'减号'
class MyList3[V] // 不变类型,泛型前面'没有符号'
// 协变
val list1_1: MyList1[Animal] = new MyList1[Dog]()
// 逆变
val list2_3: MyList2[Dog] = new MyList2[Animal]()
// 不变
val list3_2: MyList3[Dog] = new MyList3[Dog]()
泛型边界
符号 <:
和>:
都是表示泛型的边界,如:
代码演示
class MyList[V <: Dog] // 泛型 V 必须是 Dog 类或者是 Dog 类的子类,即泛型的上边界为 Dog 类
class MyList2[V >: Dog] // 泛型 V 必须是 Dog 类或者是 Dog 类的父类,即泛型的下边界为 Dog 类
val m2: MyList[Dog] = new MyList[Dog]()
val m3: MyList[ErHa] = new MyList[ErHa]()
val m4: MyList2[Animal] = new MyList2[Animal]()
val m5: MyList2[Dog] = new MyList2[Dog]()
说明: 此例中泛型声明都是 不变 的,所以声明和赋值时类型要一致
泛型协变遇到泛型边界
类的声明与赋值代码如下:
// 泛型 V 是 Dog 或者是 Dog 的子类
// +V 协变, 赋值可以是 V 或者是 V 的子类
class MyList[+V <: Dog]
val mlist1_1: MyList[ErHa] = new MyList[ErHa]()
val mlist1_2: MyList[Dog] = new MyList[ErHa]()
// 泛型 V 是 Dog 或者是 Dog 的父类
// -V 逆变, 赋值可以是 V 或者是 V 的父类
class MyList2[-V >: Dog]
val mlist2_1: MyList2[Animal] = new MyList2[Any]()
val mlist2_2: MyList2[Dog] = new MyList2[Animal]()
// 泛型 V 是 Dog 或者是 Dog 的父类
// +V 协变, 赋值可以是 V 或者是 V 的子类,但必须大于等于 Dog
class MyList3[+V >: Dog]
val mlist3_1: MyList3[Animal] = new MyList3[Dog]()
val mlist3_2: MyList3[Dog] = new MyList3[Dog]()
// 泛型 V 是 Dog 或者是 Dog 的子类
// -V 逆变, 赋值可以是 V 或者是 V 的父类,但不能超过 Dog
class MyList4[-V <: Dog]
val mlist4_1: MyList4[ErHa] = new MyList4[Dog]()
val mlist4_2: MyList4[Dog] = new MyList4[Dog]()