您的位置:首页 > 编程语言 > Java开发

JAVA 多态(以及多态在数组和ArrayList中的体现)

2013-05-14 18:47 260 查看
多态意味着,你可以把一个dog,当做一个Dog,或者Animal,或者一个Object

Animal a=new Dog();

新建一个Dog类型的对象,用一个Animal的引用来指向它
但是我们不能用a.bark(),因为Animal类中没有bark()方法.
(换言之,Animal类型的引用a就像一个遥控器,没有bark()功能的键)

需要强制类型转化:
Dog b=(Dog) a;
b.bark();

引用,参数,返回值都可以是多态的

多态在数组和ArrayList上的表现:
①各子类的实例能同时存放在父类类型的数组中
如:Animal[ ] animals=(new Dog(),new Cat(),new Rabbit);
//Dog Cat Rabbit 都是Animal的子类

②对于每个数组元素调用方法:

在这边举一个例子:
这是定义的三个类:(Animal Dog Cat里面都有方法eat())



声明:
Dog d=new Dog();
Cat c=new Cat();
Animal[ ] animals={d,c};
对每个Animal[ ]中的元素调用eat():



结果显示,调用的是Dog和Cat各自的eat(),而非Animal的eat():



但是如果Animal中没有eat();
(把Animal中的eat()方法注释掉)
编译器会报错:(需要强制类型转化Animal--->Dog)
(不免让人想起很多的以前的例子,强制类型转化来调用父类所没有的功能)



③ArrayList<T> 的多态
.基本跟Array数组是一样的
不一样的地方:



这样的以ArrayList<Animal>为参数类型的方法,不能传入ArrayList<Dog> 这样的参数
//Dog extends Animal
(如果参数类型是Animal[ ] 那么可以传入Dog[ ])
为什么会这样呢?

①为什么ArrayList不行:
因为如果写了这样一个方法:



而传入的是一个ArrayList<Dog>,那就会在狗群里面混入一只猫,这是编译器不允许的
②为什么数组行
因为数组的类型是在运行期间检查(JAVA虚拟机来报错),但集合的类型检查只会发生编译期间(编译器来报错)

③解决方案
public void takeThing(ArrayList<? extends Animal> list){}
或者
public <T extends Animal> void takeThing(ArrayList<T> list){}
二者是等价的
详见java 泛型:http://blog.163.com/it_novice/blog/static/20918306920133885429926/

解决问题的原因:add(new Cat())这类方法直接不被允许了,编译器会禁止向集合添加对象。
这样一来,就能传入很多子类型的ArrayList了

④下图要表达的意思:



可以说狗是动物,但不能说动物是狗
ArrayList前后都要一样
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐