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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 在乎.. 中级黑马   /  2013-7-29 13:39  /  1194 人查看  /  3 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 在乎.. 于 2013-7-29 16:41 编辑

  ArrayList<? extends Animal> list=new ArrayList<Cat>();
Animal al= new Animal();
    Cat cat=new Cat();
    Dog dog=new Dog();
    list.add(cat);   //错误
    list.add(al);     //错误

何解?
动物那里已经继承了。

3 个回复

倒序浏览
本帖最后由 王廷顺 于 2013-7-29 18:47 编辑

之前的解释错误很严重,现更正如下:泛型限定的作用是限定集合里面的元素只能为一种类型。楼下给出的解释很到位,这里我也引用一下,看来我对泛型的理解也不够深刻。当限定了Animal类型以及Animal的子类,那么后边的Cat应该改为Animal。ArrayList<? extends Animal>类型的引用接收的是Animal类型以及其子类型,但这个类型还不确定,所以无法添加任何对象。区分<? extends Animal>和<Animal>是关键。希望楼主不要被我之前的错误所误导。

评分

参与人数 1技术分 +1 收起 理由
神之梦 + 1 赞一个!

查看全部评分

回复 使用道具 举报
ArrayList<? extends Animal>这种一般只应用于作为参数接受一个存放泛型对象的List,获取其中所存的元素,然后调用共有的Animal中的方法。

ArrayList<? extends Animal> list=new ArrayList<Cat>();这种根本无法象普通类型一样向上转型,即你这个list不等于一个ArrayList<Animal>,也不等于一个ArrayList<Cat>。
list指向一个泛型为Cat的list,那么定然不能接受Dog对象,事实上,你用一个 ArrayList<? extends Animal>类型的引用指向它之后,他根本不能add任何对象,因为这个引用可能接受任何Animal的子类,也就是说它的实际类型可能是任意一个? extends Animal,这种模糊类型的引用根本无法添加具体类型的对象,因为允许添加就可能出错。

这点跟多态不同,一个Animal引用指向一个任意的Animal子类,就意味着可以调用这个引用执行所有Animal能做的事情。而他引用的任意一个Animal子类都具备Animal类的功能,所以不会出错。而一个ArrayList<Animal>引用理论上应该可以添加任意Animal对象,但是你让ArrayList<Animal>  list= ArrayList<Cat>;的话,list引用应该具备add一个Dog的能力,但是右边却只能add一个Cat而不能add一个Dog,左右两边功能不符,所以直接报错。 ArrayList<? extends Animal>跟ArrayList<Animal>还不一样, ArrayList<? extends Animal>本身可存储的对象都不确定,因为他允许指向任意一个泛型为animal子类的list,但指向后无法调用add方法,因为指向<Cat>就无法添加Dog,指向Dog就无法添加Cat。这种引用接收后,只能遍历容器中的元素,并调用容器中的共有方法,比如ArrayList<? extends Animal>引用中的元素都is a Animal,因此都可以调用Animal中的方法,但是却不能添加任意的元素。

评分

参与人数 1技术分 +1 收起 理由
神之梦 + 1 很给力!

查看全部评分

回复 使用道具 举报
本帖最后由 在乎.. 于 2013-7-29 16:41 编辑


:P刚看了一些大神的回答,这个答案正是我想要的,很深入
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马