Scala

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]()
上一篇 下一篇

猜你喜欢

热点阅读