java 类型协变 类型逆变_【Scala教程】(十三)Scala类型参数之协变和逆变

协变和逆变

思考一个问题,如果Professional是Master的子类,那么对于一个带类型参数的类型,比如Card[Professional]是不是Card[Master]的子类呢? 在JAVA里,不是的。因此在程序开发中,有时会造成一些麻烦。而Scala中,只要灵活使用协变和逆变,就可以解决Java泛型的问题。

通过一个老师进入会场的案例来讲解协变和逆变:

定义三个类,SeniorTeacher>MiddleTeacher>JuniorTeacher。

class JuniorTeacher extends MiddleTeacher{}

class MiddleTeacher extends SeniorTeacher{}

class SeniorTeacher {}

现在已知,中级老师可以进入会场。也就是enterMeeting的参数是Card[MiddleTeacher]。

class Card[+T](val name:String) {

def enterMeeting(card: Card[MiddleTeacher]): Unit = {

println(card.name +"you can enter")

}

}

那么我如果希望初级老师可以进入会场,即我希望中级的子类可以进入会场,该怎么办??—>答案:协变

如果我希望高级老师可以进入会场,即我希望中级的父类可以进入会场,该怎么办??—>答案:逆变

协变

假设A的子类是B,List[B]也是List[A]的子类。也就是被参数化类型的泛化方向与参数类型的方向是一致的,就称为协变。

此列中,MiddleTeacher的子类是JuniorTeacher,那么Card[JuniorTeacher]也是Card[MiddleTeacher]的子类,就称为协变,用+T表示。

/**

* 协变 (+T)

* 中级及中级以下的老师,可以进入会场

*/

class Card[+T](val name:String) {

def enterMeeting(card: Card[MiddleTeacher]): Unit = {

println(card.name +"you can enter")

}

}

object Card{

def main(args: Array[String]): Unit = {

var zhangsan = new Card[JuniorTeacher]("zhangsan")

var lisi = new Card[MiddleTeacher]("lisi")

var wangwu = new Card[SeniorTeacher]("wangwu")

zhangsan.enterMeeting(zhangsan)

lisi.enterMeeting(lisi)

// wangwu.enterMeeting(wangwu) 高级老师无法进入会场

}

}

逆变

假设A的子类是B,List[B]却是List[A]的父类。也就是被参数化类型的泛化方向与参数类型的方向是相反的,即与原来的父子关系正相反,就称为逆变。

此列中,SeniorTeacher的子类是MiddleTeacher,可Card[MiddleTeacher]是Card[SeniorTeacher]的父类,就称为逆变,用-T表示。

/**

* 逆变 (-T)

* 中级及中级以上的老师,可以进入会场

*/

class Card[-T](val name:String) {

def enterMeeting(card: Card[MiddleTeacher]): Unit = {

println(card.name +"you can enter")

}

}

object Card{

def main(args: Array[String]): Unit = {

var zhangsan = new Card[JuniorTeacher]("zhangsan")

var lisi = new Card[MiddleTeacher]("lisi")

var wangwu = new Card[SeniorTeacher]("wangwu")

// zhangsan.enterMeeting(zhangsan) 初级老师无法进入会场

lisi.enterMeeting(lisi)

wangwu.enterMeeting(wangwu)

}

}

BDStar原创文章。发布者:Liuyanling,转载请注明出处:http://bigdata-star.com/archives/1657

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值