public class Generic {
public static void main(String[] args) {
/*<? extends T>:是指 “上界通配符(Upper Bounds Wildcards)”适用于频繁往外读
<? super T>:是指 “下界通配符(Lower Bounds Wildcards)”适用于经常往里写*/
//plate<fruit> p=new plate<apple>(new apple());“装苹果的盘子”无法转换成“装水果的盘子”
plate<? extends fruit> p=new plate<apple>(new apple());//一个能放水果以及一切其他派生类的盘子
fruit f1=p.getItem();
Object o1=p.getItem();//因为编译器不知道取出来的东西是fruit还是apple(类型擦除),所以就统一给父类,相当于完成了多态
//apple a1=p.getItem(); //error这个是因为无法实现多态
//p.setItem(new apple());//error
//p.setItem(new fruit());//error
plate<? super fruit> p2=new plate<fruit>(new fruit());
p2.setItem(new apple());
p2.setItem(new fruit());
//fruit f2=p2.getItem();//error
Object o2=p2.getItem();
//apple a2=p2.getItem(); //error
}
}
class fruit{
}
class apple extends fruit{
}
//容器:盘子
class plate<T>{
private T item;
public plate(T item) {
this.item = item;
}
public T getItem() {
return item;
}
public void setItem(T item) {
this.item = item;
}
1.如上代码所述,我们现在有水果类和苹果类,苹果类继承了水果类,现在有一个盘子类,注意盘子类后面<T>表示泛型,也就是可以装任意类别的引用
2. new plate<apple>(new apple())这句代码的意思就是新创建了一个苹果对象,并把这个苹果对象传进了盘子类里,因为苹果对象只用一次所以我们用匿名对象
3.现在我们试图完成多态,用父类引用指向子类对象 plate<fruit> p=new plate<apple>(new apple()) 然后发现失败了,这是因为多态只能针对对象
比如我们可以用 fruit p=new apple();水果是有子父类关系的,但是盘子没有,所以上一句代码失败了
4.但是现在我们就想用这个盘子装所有水果,既可以装父类水果,也可以装子类苹果,java为我们提供了通配符的概念
<? extends T>:是指 “上界通配符(Upper Bounds Wildcards)”适用于频繁往外读
?就表示可以装任意对象的泛型,extends表示可以装T本身和继承了T的一切子类
plate<? extends fruit> p 如上所述就表示可以装fruit以及一切继承了fruit的盘子,在这里也就是包括了水果本身和苹果
5.这样我们就能把完成盘子间的多态了,我们建了一个可以装水果和一切子类的盘子 plate<? extends fruit> p=new plate<apple>(new apple());
6.tips其他一些使用的注意对象见具体代码,只要记住上限通配符适合频繁往外读,下限通配符适合频繁往里写就行
例如我们的ArrayList 中的addAll()方法就用的是上限统配符,把子类的东西读出来加到父类里
|
|