scala-19 协变、逆变、非变

本文介绍了Scala中协变、逆变和非变的概念。通过示例说明了协变如何使类型B的Pair成为类型A的Pair的子类型,逆变则是类型A的Pair成为类型B的Pair的子类型,而非变则保持不变,不产生从属关系。
摘要由CSDN通过智能技术生成

协变、逆变、非变


由于擦拭法的原因,泛型中的的元素类型即使有继承关系,对应的泛型也没有相应的继承关系。
示例

class Pair[T](a:T)

object Pair {
  def main(args: Array[String]): Unit = {
    val p1 = new Pair("hello")
    // 编译报错,无法将p1转换为p2
    //hello->String  
    //String->AnyRef  String有个父类型AnyRef
    //但是Pair[String]不是Pair[AnyRef]的子类型 报错
    val p2:Pair[AnyRef] = p1

    println(p2)
  }
}
  • AnyRef是String的父类,但是Pair[AnyRef]和Pair[String]直接没有继承关系

scala中引入了协变 逆变和非变的概念
在这里插入图片描述

协变

class Pair[+T],这种情况是协变。类型B是A的子类型,Pair[B]可以认为是Pair[A]的子类型。这种情况,参数化类型的方向和类型的方向是一致的

逆变

class Pair[-T],这种情况是逆变。类型B是A的子类型,Pair[A]反过来可以认为是Pair[B]的子类型。这种情况,参数化类型的方向和类型的方向是相反的

非变

class Pair[T]{},这种情况就是非变(默认),类型B是A的子类型,Pair[A]和Pair[B]没有任何从属关系,这种情况和Java是一样的

示例

class Super
class Sub extends Super

//非变
class Temp1[A](title: String)
//协变
class Temp2[+A](title: String)
//逆变
class Temp3[-A](title: String)

object Covariance_demo {
  def main(args: Array[String]): Unit = {
    val a = new Sub()
    // 没有问题,Sub是Super的子类
    val b:Super = a

    // 非变
    val t1:Temp1[Sub] = new Temp1[Sub]("测试")
    // 报错!默认不允许转换
    // val t2:Temp1[Super] = t1

    // 协变
    val t3:Temp2[Sub] = new Temp2[Sub]("测试")
    val t4:Temp2[Super] = t3
    
    // 逆变
    val t5:Temp3[Super] = new Temp3[Super]("测试")
    val t6:Temp3[Sub] = t5
  }
}

总结

  • C[+T]:如果A是B的子类,那么C[A]是C[B]的子类。
  • C[-T]:如果A是B的子类,那么C[B]是C[A]的子类。
  • C[T]: 无论A和B是什么关系,C[A]和C[B]没有从属关系。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值