多态是同一个行为具有多个不同表现形式或形态的能力。
多态就是同一个接口,使用不同的 实例而执行不同的操作。
多态的原因
多态的存在必须满足下面三个条件:
1.继承 2.重写 3.父类引用指向子类对象。(比如:Parent p = new Child())
理解第三点中“父类引用指向子类对象”这句话,是理解多态的关键所在。我们创建了一个子类对象,然后却将它与一个父类的引用关联了起来。 为什么可以这样?如此创建的对象p倒是是什么?怎么理解它?
首先,新创建的对象是子类对象,从new Child()中就能看出来。然后用一个父类应用指向它,可以理解为将这个子类对象包装成了父类对象。这个时候,子类特有的东西被隐藏了起来,留下来可见的东西就是和父类公有的东西。但要注意的是,这个子类只是被包成了父类,而不是转变成了父类,他重写父类的方法依然是重写后的方法,而不是父类的方法。他自己独有的东西都还在,如果我们把这个父类引用强转为子类对象,那一切被包裹隐藏的东西就又会显现出来。
为什么要这样做呢?这样就抹平了子类之间的差异,让我们将他们都视为同一种类型来处理。比如我们有个父类动物,父类下有很多子类猫,狗,乌龟等等,如果没有多态,那么虽然他们之间有这种继承关系,我们也只能将他们当作一个个截然不同的类来处理。如果在程序的其他地方需要使用这些类,就需要为每个不同的类编写各种不同的方法。比如:超市管理系统中的,客户端传输数据给服务器,数据可能是Product对象,可能是整数,可能是字符串,可能是布尔类型,如此我们就需要编写传输各种不同数据类型的方法。可是如果我们通过多态,把所有数据都统一为Object类型,那不管我要传输什么数据,都只需要一个传输对象的方法就可以了。数据被接受了以后再通过强转,就还原回了我们想要的数据类型。
多态中方法调用的过程
当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法,而不是父类中被重写的方法。要想调用父类中被重写的方法,则必须使用关键字,super。
多态的好处
- 消除类型之间的耦合关系
- 可替换性
- 可扩充性
- 接口性
- 灵活性
- 简化性
下面是我写的一个体现多态的小程序
//父类,抽象类人
public abstract class Person {
int age;
String name;
public abstract void run();
}
//子类一,实现类,男人,重写了父类的run方法,并且有自己的sleep方法
public class Man extends Person {
public void run() {
System.out.println("男人在奔跑");}
public void sleep() {
System.out.println("男人在睡觉");
}
}
//子类二,实现类,女人,重写了父类的run方法
public class Women extends Person {
@Override
public void run() {
System.out.println("女人在奔跑");
}
}
//测试类,创建了父类列表,加入两个子类对象,都调用run方法
public class Test {
public static void main(String[] args) {
Person m =new Man();
Person w= new Women();
ArrayList<Person> list = new ArrayList<Person>();
list.add(w);
list.add(m);
list.get(0).run();
//list.get(1).sleep(); sleep()方法在强转回Man之前,不可见。
list.get(1).run();
Person a= list.get(1);
Man b=(Man)a;
b.sleep();
}
}