水果类:
class Fruits{
}
苹果类:
class Apple extends Fruits{
}
青苹果类:
class GreenApple extends Apple {
}
梨子类:
class Pear extends Fruits{
}
向上造型一个泛型对象的引用 <?extends T>
向下造型一个泛型对象的引用 <? super T>
List<?extends Fruits> fruits = new ArrayList<Apple>();
fruits.add(new xxx());//xxx表示任意类型,add形参类型是Fruits的的类型或是Fruits的子类,但是具体是那个类型不确定,所以编译错误
Fruits aFruit = fruits.get(0);//get方法返回的类型是Fruits的的类型或是Fruits的子类, 所以可以用父类引用接收子类的引用,编译通过
所以说<?extends T>用于读取数据;
List<? super Apple> fruits = new ArrayList<Fruits >();
fruits.add(Apple或 Apple子类对象的引用); //add形参类型是Apple的的类型或是Apple的父类,所以能接收所有的Apple或 Apple子类对象的引用)
Apple aApple = fruits.get(0); //get方法返回的类型是Apple的的类型或是Apple的父类,但是具体是那个类型不确定,所以也没方法指定一个类型引用来接收它,自然编译错误
所以说<? super T>用于写入数据;
总结:
如果你想从一个数据类型里获取数据,使用 ? extends 通配符
如果你想把对象写入一个数据结构里,使用 ? super 通配符
如果你既想存,又想取,那就别用通配符。
重点理解这句话:父类的引用可以接收子类的实例对象的引用(多态性)
|