Java面向对象之多态
多态这个词来源于希腊语,意为“多种形态”。简单来说,多态允许我们使用一个父类引用来指向其子类对象,从而在运行时动态地决定调用哪个方法。
假设我们有一个父类 Person
,它有三个子类:Student
、Teacher
、Worker
,现在写一个方法sayHello()
,如果不用多态,我们只能写成这样:
// 方法1: 针对学生
public void greet(Student student) {student.sayHello();
}// 方法2: 针对老师
public void greet(Teacher teacher) {teacher.sayHello();
}// 方法3: 针对工人
public void greet(Worker worker) {worker.sayHello();
}
每增加一种新的人物类型,就必须再写一个新方法。这会导致代码冗余、难以维护,并且无法通用。
多态的出现正是为了解决这个问题。它允许我们创建一个通用的方法,只接受Person类型的参数,而不管传入的实际对象是Student、Teacher还是Worker。
多态的前提
要实现多态,必须满足三个条件:
- 继承:子类继承父类。
- 方法重写:子类重写父类的方法。
- 父类引用指向子类对象。
多态的语法:父类引用指向子类对象
// 标准的创建对象语法
Dog myDog = new Dog(); // myDog的引用类型和实际对象类型都是Dog// 多态的创建对象语法
Animal myAnimal = new Dog(); // myAnimal的引用类型是Animal,但实际对象类型是Dog
示例代码:动物吃东西
// 父类:Animal.java
class Animal {public void eat() {System.out.println("Animal is eating.");}
}// 子类1:Dog.java
class Dog extends Animal {@Overridepublic void eat() {System.out.println("The dog is eating dog food.");}
}// 子类2:Cat.java
class Cat extends Animal {@Overridepublic void eat() {System.out.println("The cat is eating fish.");}
}// 主程序:Main.java
public class Main {public static void main(String[] args) {// 父类引用指向子类对象Animal myDog = new Dog();Animal myCat = new Cat();// 调用相同的方法,但输出结果不同myDog.eat(); // 输出: The dog is eating dog food.myCat.eat(); // 输出: The cat is eating fish.// 我们还可以创建一个通用的方法来处理makeAnimalEat(myDog); // 输出: The dog is eating dog food.makeAnimalEat(myCat); // 输出: The cat is eating fish.}public static void makeAnimalEat(Animal animal) {// 在运行时,JVM会根据实际的对象类型来调用对应的方法animal.eat();}
}
在编译阶段,编译器只知道 myDog
和 myCat
是 Animal 类型
;当调用eat()
方法时,Java虚拟机(JVM)会根据实际创建的对象类型(即new Dog()
和new Cat()
)来决定执行哪个版本的eat()
方法。
多态的两种形式
多态通常分为两种类型:
-
编译时多态(静态多态):主要指方法重载(Overloading)。它在编译阶段就已经确定了调用哪个方法。例如,同一个类中可以有多个同名但参数列表不同的方法。
-
运行时多态(动态多态):这才是我们通常所说的多态,通过方法重写(Overriding)和父类引用指向子类对象实现。它在程序运行时才能确定调用哪个方法。
多态的优点
-
可扩展性:当需要添加新的子类时(比如添加一个Bird类),我们只需要让它继承Animal并重写eat()方法即可,无需修改其他现有代码,makeAnimalEat()方法依然可以正常工作。
-
可维护性:它简化了代码的复杂性。你可以用一个统一的接口(父类)来处理多种不同的对象,而不用写一大堆if-else或switch语句来判断对象的具体类型。
-
代码简洁性:它允许我们编写更加通用和抽象的代码。