多态指的是同一个行为具有多个不同表现形式和形态的能力。多态就像是一个接口一样,使用不同的实例就会执行不同的操作,例如,同样是水的成分,有液态水及固态水(也就是冰)等多种形态;同样是二氧化碳,存在气态及液态等多种形态;同样是猫科动物,有猫和老虎等不同表现形式。
那么Java中实现多态的三个必要条件如下。
- 继承:在多态中必须存在有继承关系的子类和父类。
- 重写:子类对父类中某些方法进行重新定义,在调用这些方法时就会调用子类的方法。
- 向上转型:在多态中需要将子类的引用赋给父类对象,只有这样该引用才能够具备调用父类的方法和子类方法的能力。
那么多态具体表现形式是什么,看一下代码:
先写这样几个类:Car类,Sallon_car类,Truck类
//父类汽车类
public class Car {
String engine; // 引擎
String Wheel; // 车轮
// ....其他属性
public void run() { // 方法
// 定义车跑动的行为
System.out.println("汽车在奔跑!");
}
}
//子类轿车类
public class Saloon_car extends Car {
String airbag; //安全气囊
public void run() { //不用父类方法,重新编写的run方法
//定义轿车
System.out.println("轿车在高速路上奔驰!");
}
}
//子类卡车类
public class Truck extends Car {
String carport; // 货舱
public void run() { // 不用父类方法,重新编写的run方法
System.out.println("卡车在工地上忙碌!");
}
}
然后写CarTest测试类对三个类进行测试
public class CarTest {
public void test(Car car) {
car.run(); //引用car里run方法
}
public static void main(String[] args) {
CarTest ct = new CarTest(); //对象实例化ct
//产生普通汽车
Car car = new Car(); //对象实例化car
ct.test(car); //调用CarTest中run方法
//产生轿车
car= new Saloon_car();
ct.test(car);
//产生卡车
car = new Truck();
ct.test(car);
}
}
运行结果如下:
可以看到,同样是 Car 类的对象,既可以是汽车,也可以是卡车,还可以是轿车,父类句柄可以接收子类对象。在调用 test()方法时,传递的都是 Car类的对象,但是输出什么样的结果取决于该父类句柄所绑定(指向)的到底是什么对象,这就是多态性的外在体现,是在 Java 中通常叫作“run-time binding(运行时绑定)”。运行时绑定的目的就是在代码运行的时候能够判断对象的类型,它能使程序变得可扩展而不需要重新编译已存在的代码。还要注意一点,由父类引用创建的对象,只能调用子类从父类继承的方法(当然包含重写的方法),不能调用自己扩展的方法。就像我们说“豹子是动物”(向上转型),也可说“豹子会奔跑”(调用从父类继承的方法),而不能说“动物是豹子”(向下转型),也不能说“动物会爬树”(向上转型的对象不能调用子类对象扩展的方法)。