scala的协变、逆变、非变

协变、逆变、非变
spark的源代码中大量使用到了协变、逆变、非变,学习该知识点对我们将来阅读spark源代码很有帮助。
来看一个类型转换的问题:

class Pair[T]

object Pair {
  def main(args: Array[String]): Unit = {
    val p1 = Pair("hello")
    // 编译报错,无法将p1转换为p2
    val p2:Pair[AnyRef] = p1

    println(p2)
  }
}

如何让带有泛型的类支持类型转换呢?
非变
语法格式
class Pair[T]{}
默认泛型类是非变的
类型B是A的子类型,Pair[A]和Pair[B]没有任何从属关系
Java是一样的
在这里插入图片描述
协变
语法格式
class Pair[+T]
类型B是A的子类型,Pair[B]可以认为是Pair[A]的子类型
参数化类型的方向和类型的方向是一致的
逆变
语法格式
class Pair[-T]
类型B是A的子类型,Pair[A]反过来可以认为是Pair[B]的子类型
参数化类型的方向和类型的方向是相反的
示例
示例说明
定义一个Super类、以及一个Sub类继承自Super类
使用协变、逆变、非变分别定义三个泛型类
分别创建泛型类来演示协变、逆变、非变
参考代码:

class Super
class Sub extends Super

class Temp1[T]
class Temp2[+T]
class Temp3[-T]

def main(args: Array[String]): Unit = {
    val a:Temp1[Sub] = new Temp1[Sub]
    // 编译报错
    // 非变
    //val b:Temp1[Super] = a

    // 协变
    val c: Temp2[Sub] = new Temp2[Sub]
    val d: Temp2[Super] = c

    // 逆变
    val e: Temp3[Super] = new Temp3[Super]
    val f: Temp3[Sub] = e
}

在这里插入图片描述

发布了158 篇原创文章 · 获赞 339 · 访问量 23万+

猜你喜欢

转载自blog.csdn.net/qq_45765882/article/details/104336063