ITPub博客

首页 > 应用开发 > Java > Scala协变、逆变

Scala协变、逆变

原创 Java 作者:541732025 时间:2016-03-25 11:18:32 0 删除 编辑
先来看看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]的父类型。

点击(此处)折叠或打开

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

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

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

  15. }

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

下一篇: MySQL锁机制
请登录后发表评论 登录
全部评论

注册时间:2013-05-23

  • 博文量
    127
  • 访问量
    479243