A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 成都黑马 初级黑马   /  2018-4-27 09:51  /  660 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

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()方法就用的是上限统配符,把子类的东西读出来加到父类里

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马