先来看看Java中泛型上下界的例子:
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]的父类型。
点击(此处)折叠或打开
- List<? extends Number> covariantList;
-
- covariantList = new ArrayList<String>(); //wrong
- covariantList = new ArrayList<Integer>(); //right
- covariantList = new ArrayList<Long>(); //right
- //<? extends T>类似于Scala中的协变,即,如果A是T的子类,那么List<A>是List<? extends T>的子类
-
- covariantList.add(new Integer(1)); //wrong
- covariantList.add(new Long(1));//wrong
- covariantList.add(new Object());//wrong
- covariantList.add(null); //right
- //Java为了保护类型一致(因为List实例可能是List<Integer>也有可能是List<Long>),所以禁止向<? extends T>中添加任何对象,除了null。
-
- Number a = covariantList.get(0); //right
- Integer b = covariantList.get(0); //wrong
- //另外,只能以最宽泛的方式获取List元素
点击(此处)折叠或打开
- List<? super Number> contravariantList;
-
- contravariantList = new ArrayList<Number>(); //right
- contravariantList = new ArrayList<Object>(); //right
- contravariantList = new ArrayList<Integer>(); //wrong
- //<? super T>类似于Scala中的逆变,即,如果A是T的父类,那么List<A>是List<? super T>的子类
-
- contravariantList.add(new Integer(1)); //OK
- contravariantList.add(new Double(1)); //OK
- contravariantList.add(new Object()); //wrong
- //不管实例是何种List实例,但肯定是Number或者是其父类,所以可以添加子类(Integer、Double)
-
- Number c = contravariantList.get(1); //wrong
- Object d = contravariantList.get(2); //right
- //同样也只能以最宽泛的方式获取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")
}
}
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/