黑马程序员技术交流社区
标题:
关于泛型的问题,会的冒个泡吧
[打印本页]
作者:
在乎..
时间:
2013-7-29 13:39
标题:
关于泛型的问题,会的冒个泡吧
本帖最后由 在乎.. 于 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); //错误
何解?
动物那里已经继承了。
作者:
王廷顺
时间:
2013-7-29 16:13
本帖最后由 王廷顺 于 2013-7-29 18:47 编辑
之前的解释错误很严重,现更正如下:泛型限定的作用是限定集合里面的元素只能为一种类型。楼下给出的解释很到位,这里我也引用一下,看来我对泛型的理解也不够深刻。当限定了Animal类型以及Animal的子类,那么后边的Cat应该改为Animal。ArrayList<? extends Animal>类型的引用接收的是Animal类型以及其子类型,但这个类型还不确定,所以无法添加任何对象。区分<? extends Animal>和<Animal>是关键。希望楼主不要被我之前的错误所误导。
作者:
longlangcx
时间:
2013-7-29 16:19
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中的方法,但是却不能添加任意的元素。
作者:
在乎..
时间:
2013-7-29 16:39
本帖最后由 在乎.. 于 2013-7-29 16:41 编辑
longlangcx 发表于 2013-7-29 16:19
ArrayList
:P刚看了一些大神的回答,这个答案正是我想要的,很深入
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2