Java 多态 (Polymorphism)详解
多态是面向对象编程(OOP)中的一个重要概念,它允许一个对象在不同的上下文中表现出不同的行为。在 Java 中,多态主要通过方法重载(Method Overloading)和方法重写(Method Overriding)来实现。
什么是多态 ?
多态 的概念来源于化学中的术语,指一个物体可以以不同的形式存在。例如,碳可以以煤、石墨和金刚石三种不同的结晶形式存在。同样,在 Java 中,多态是指一个对象可以以不同的方式执行操作。
示例
package polymorphism;
class AnimalSounds {
public void Sound() {
System.out.println("The animals make different sounds when asked to speak. For example:");
}
}
class Cow extends AnimalSounds {
@Override
public void Sound() {
System.out.println("The cow says: moh moh");
}
}
class Cat extends AnimalSounds {
@Override
public void Sound() {
System.out.println("The cat says: mew mew");
}
}
class Dog extends AnimalSounds {
@Override
public void Sound() {
System.out.println("The dog says: bow wow");
}
}
public class AnimalMain {
public static void main(String[] args) {
AnimalSounds animal = new AnimalSounds();
AnimalSounds cow = new Cow();
AnimalSounds cat = new Cat();
AnimalSounds dog = new Dog();
animal.Sound();
cow.Sound();
cat.Sound();
dog.Sound();
}
}
输出:
The animals make different sounds when asked to speak. For example:
The cow says: moh moh
The cat says: mew mew
The dog says: bow wow
多态的特征
-
方法的行为在不同情况下不同:
- 同一个方法在不同的对象中可以有不同的实现。
-
方法的行为取决于提供的数据:
- 方法的执行结果依赖于传入的参数。
-
允许类中有同名但不同类型的成员或方法:
- 例如,方法重载允许类中有多个同名但参数不同的方法。
-
支持隐式类型转换:
- 例如,子类对象可以赋值给父类引用。
多态的类型
多态在 Java 中主要分为两种类型:
-
编译时多态(Compile-Time Polymorphism):
- 也称为静态多态或早期绑定。
- 主要通过方法重载(Method Overloading)实现。
-
运行时多态(Run-Time Polymorphism):
- 也称为动态多态或晚期绑定。
- 主要通过方法重写(Method Overriding)实现。
编译时多态(Compile-Time Polymorphism)
方法重载(Method Overloading):
- 同一个类中可以有多个同名但参数不同的方法。
- 方法的选择在编译时确定。
package polymorphism;
public class Addition {
public int add(int x, int y) {
return (x + y);
}
public double add(double d, double e, double f, double g) {
return (d + e + f + g);
}
public double add(double a, double b) {
return (a + b);
}
public static void main(String[] args) {
Addition a = new Addition();
System.out.println(a.add(25, 30));
System.out.println(a.add(10.0, 15.0, 20.0, 25.0));
System.out.println(a.add(127.5, 123.5));
}
}
输出:
55
70.0
251.0
运算符重载(Operator Overloading):
- Java 不支持运算符重载,以避免歧义。
运行时多态(Run-Time Polymorphism)
方法重写(Method Overriding):
- 子类可以重写父类的方法,提供不同的实现。
- 方法的选择在运行时确定。
package polymorphism;
class CargoPilot {
public void FlyPlane() {
System.out.println("This is the Cargo Pilot, Ready to Take off");
}
}
class CivilianPilot extends CargoPilot {
@Override
public void FlyPlane() {
System.out.println("This is the Civilian Pilot, Ready to Takeoff");
}
}
public class Takeoff {
public static void main(String[] args) {
CargoPilot cpObj = new CargoPilot();
cpObj.FlyPlane();
CargoPilot civilianObj = new CivilianPilot();
civilianObj.FlyPlane();
}
}
输出:
This is the Cargo Pilot, Ready to Take off
This is the Civilian Pilot, Ready to Takeoff
编译时多态 vs. 运行时多态
特征 | 编译时多态 | 运行时多态 |
---|---|---|
方法调用处理 | 由编译器处理 | 编译器无法控制运行时的方法调用 |
灵活性 | 较低,需要在编译时处理所有方法调用 | 较高,方法调用在运行时处理 |
执行时间 | 较短 | 较长 |
方法绑定 | 在编译时完成 | 在运行时完成 |
发生情况 | 方法重载和运算符重载 | 方法重写 |
super
关键字
super
关键字用于引用父类的对象或方法。每当创建子类的实例时,编译器会隐式地创建父类的实例,super
引用变量将指向父类的实例。
package polymorphism;
public class SuperKeyWord {
public static void main(String[] args) {
Triangle triangle = new Triangle();
triangle.countSides();
}
}
class Square {
int sides = 4;
}
class Triangle extends Square {
int sides = 3;
public void countSides() {
System.out.println("Number of sides in the triangle: " + sides);
System.out.println("Number of sides in the square: " + super.sides);
}
}
输出:
Number of sides in the triangle: 3
Number of sides in the square: 4
多态的优点
-
代码复用:
- 通过多态,可以重用已有的代码,提高代码的复用性和可维护性。
-
支持单一变量名处理多种数据类型:
- 例如,父类引用可以指向不同子类的对象。
-
减少不同功能之间的耦合:
- 通过多态,可以降低不同功能之间的依赖关系。
多态的缺点
-
性能问题:
- 多态可能会导致性能下降,特别是在实时应用中。
-
代码可读性降低:
- 多态可能会使代码变得复杂,降低代码的可读性。
-
实现难度:
- 对于初学者来说,理解和实现多态可能会有一定的挑战。
总结
通过本教程,你已经了解了 Java 中多态的基本概念、特征、类型以及 super
关键字的使用。这些知识将帮助你在 Java 应用程序中实现更高的代码复用性和灵活性,这是 Java 面向对象编程(OOP)的一个重要方面。