109. Java 继承 - 多态
多态(Polymorphism)是面向对象编程中一个非常重要的概念,它源自于生物学中“多个形态”的原理,即一个实体可以表现出多种不同的形式。对于 Java 编程来说,多态使得一个父类引用可以指向子类对象,从而根据实际对象的类型调用相应的方法。这种特性是 Java 动态绑定的一个体现,允许不同对象以统一的接口表现不同的行为。
多态性的核心在于:同一方法在不同对象上有不同的实现,具体调用哪个方法取决于对象的实际类型,而非引用的类型。
示例与解释
我们将通过修改一个名为 Bicycle 的类来演示多态性。首先定义 Bicycle 类,并添加一个方法 printDescription(),用于打印自行车的描述。
public class Bicycle {
private int cadence;
private int speed;
private int gear;
public Bicycle(int startCadence, int startSpeed, int startGear) {
cadence = startCadence;
speed = startSpeed;
gear = startGear;
}
public void printDescription() {
System.out.println("\nBike is in gear " + gear
+ " with a cadence of " + cadence +
" and travelling at a speed of " + speed + ". ");
}
}
MountainBike 子类
接下来,我们定义一个名为 MountainBike 的子类,继承自 Bicycle 类,并添加一个新的字段 suspension(前减震类型)。这个类还重写了 printDescription() 方法,以便输出更多信息,如减震类型。
public class MountainBike extends Bicycle {
private String suspension;
public MountainBike(int startCadence, int startSpeed, int startGear, String suspensionType) {
super(startCadence, startSpeed, startGear);
this.setSuspension(suspensionType);
}
public String getSuspension() {
return this.suspension;
}
public void setSuspension(String suspensionType) {
this.suspension = suspensionType;
}
@Override
public void printDescription() {
super.printDescription(); // 调用父类方法
System.out.println("The MountainBike has a " + getSuspension() + " suspension.");
}
}
在 MountainBike 类中,printDescription() 方法覆盖了父类的方法,除了输出关于自行车的基本信息外,还添加了关于悬挂系统的信息。
RoadBike 子类
再定义一个名为 RoadBike 的子类,它也继承自 Bicycle 类,并且添加一个新属性 tireWidth(轮胎宽度)。该类同样重写了 printDescription() 方法,输出关于轮胎宽度的描述。
public class RoadBike extends Bicycle {
private int tireWidth;
public RoadBike(int startCadence, int startSpeed, int startGear, int newTireWidth) {
super(startCadence, startSpeed, startGear);
this.setTireWidth(newTireWidth);
}
public int getTireWidth() {
return this.tireWidth;
}
public void setTireWidth(int newTireWidth) {
this.tireWidth = newTireWidth;
}
@Override
public void printDescription() {
super.printDescription(); // 调用父类方法
System.out.println("The RoadBike has " + getTireWidth() + " MM tires.");
}
}
在 RoadBike 类中,printDescription() 方法再次覆盖了父类的方法,输出了轮胎宽度的信息。
测试程序
现在,编写一个测试程序,创建 Bicycle 类、MountainBike 类和 RoadBike 类的实例,并调用它们的 printDescription() 方法:
public class TestBikes {
public static void main(String[] args) {
Bicycle bike01, bike02, bike03;
bike01 = new Bicycle(20, 10, 1);
bike02 = new MountainBike(20, 10, 5, "Dual");
bike03 = new RoadBike(40, 20, 8, 23);
bike01.printDescription();
bike02.printDescription();
bike03.printDescription();
}
}
输出结果
Bike is in gear 1 with a cadence of 20 and travelling at a speed of 10.
Bike is in gear 5 with a cadence of 20 and travelling at a speed of 10.
The MountainBike has a Dual suspension.
Bike is in gear 8 with a cadence of 40 and travelling at a speed of 20.
The RoadBike has 23 MM tires.
分析
在这个例子中,三个 Bicycle 类型的变量分别引用了不同类型的对象:Bicycle、MountainBike 和 RoadBike。即使这些变量的类型都是 Bicycle,Java 虚拟机(JVM)依然能够根据实际的对象类型(MountainBike 或 RoadBike)调用相应的 printDescription() 方法。这个过程称为虚拟方法调用,它展示了多态的一个重要特性。
通过多态,我们可以通过统一的接口(在此示例中为 Bicycle 类型的变量)操作不同类型的对象,且每个对象根据自己的类型执行不同的行为。
总结
- 多态的概念:同一个方法在不同对象上有不同的表现,具体调用哪个方法由对象的实际类型决定,而不是引用的类型。
- 方法重写:子类可以重写父类的方法,以提供特定的实现。
- 虚拟方法调用:Java 在运行时根据对象的实际类型来决定调用哪个方法。