Scala协变、逆变

先来看看Java中泛型上下界的例子:

点击(此处)折叠或打开

  1.         List<? extends Number> covariantList;

  2.         covariantList = new ArrayList<String>(); //wrong
  3.         covariantList = new ArrayList<Integer>(); //right
  4.         covariantList = new ArrayList<Long>(); //right
  5.         //<? extends T>类似于Scala中的协变,即,如果A是T的子类,那么List<A>是List<? extends T>的子类

  6.         covariantList.add(new Integer(1)); //wrong
  7.         covariantList.add(new Long(1));//wrong
  8.         covariantList.add(new Object());//wrong
  9.         covariantList.add(null); //right
  10.         //Java为了保护类型一致(因为List实例可能是List<Integer>也有可能是List<Long>),所以禁止向<? extends T>中添加任何对象,除了null。

  11.         Number a = covariantList.get(0); //right
  12.         Integer b = covariantList.get(0); //wrong
  13.         //另外,只能以最宽泛的方式获取List元素

点击(此处)折叠或打开

  1.         List<? super Number> contravariantList;

  2.         contravariantList = new ArrayList<Number>(); //right
  3.         contravariantList = new ArrayList<Object>(); //right
  4.         contravariantList = new ArrayList<Integer>(); //wrong
  5.         //<? super T>类似于Scala中的逆变,即,如果A是T的父类,那么List<A>是List<? super T>的子类

  6.         contravariantList.add(new Integer(1)); //OK
  7.         contravariantList.add(new Double(1)); //OK
  8.         contravariantList.add(new Object()); //wrong
  9.         //不管实例是何种List实例,但肯定是Number或者是其父类,所以可以添加子类(Integer、Double)
  10.        
  11.         Number c = contravariantList.get(1); //wrong
  12.         Object d = contravariantList.get(2); //right
  13.         //同样也只能以最宽泛的方式获取List元素

Scala中的协变、逆变

对于泛型类C[+T],现在有具体类型A、B,如果B是A的子类,那么C[B]也是C[A]的子类,我们称这个类C支持协变。相反,C[-T]则称之为逆变
当我们定义一个协变类型List[A+]时,List[Child]可以是List[Parent]的子类型。
当我们定义一个逆变类型List[-A]时,List[Child]可以是List[Parent]的父类型。

点击(此处)折叠或打开

class Person
class Student extends Person
class C[+T](val args: T)
class S[+T](arg : T) extends C[T](arg) //对于子类,同样要支持协变或者逆变
trait Friend[-T]{
  def makeFriend(somebody: T)
}

object Variance {
  def makeFriendWithYou(s: Student, f: Friend[Student]){f.makeFriend(s)}
  def main(args: Array[String]) {
    val value : C[Person] = new C[Student](new Student)

// List<? extends Oject> list = new ArrayList<String>()
    val list : List[_ <: Any] = List[String]("Spark")
  }

}

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/28912557/viewspace-2063602/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/28912557/viewspace-2063602/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值