Java基础:Java 面向对象编程(OOP)之【多态性】
·
多态(Polymorphism) 是面向对象编程(OOP)的四大核心特性之一(封装、继承、多态、抽象),其字面意思是“多种形态”。在 Java 中,多态指的是:同一个引用变量,调用同一个方法,在运行时根据实际对象类型表现出不同的行为。
🌟 核心思想:
“编译时看类型,运行时看对象。”
一、多态的前提条件
Java 中实现多态必须同时满足以下三个条件:
- 继承或实现关系(子类继承父类,或类实现接口);
- 方法重写(Override)(子类重写父类的方法);
- 父类引用指向子类对象(向上转型)。
Animal animal = new Dog(); // 父类引用指向子类对象(向上转型)
animal.makeSound(); // 调用的是 Dog 的 makeSound()
二、多态的两种主要形式
1. 编译时多态(静态多态) → 方法重载(Overloading)
- 同一个类中,方法名相同但参数列表不同;
- 在编译期就确定调用哪个方法;
- 不属于 OOP 多态的核心讨论范畴(通常“多态”指运行时多态)。
void print(int a) { ... }
void print(String s) { ... }
2. 运行时多态(动态多态) → 方法重写(Overriding)✅(重点!)
- 子类重写父类方法;
- 在运行时根据实际对象类型决定调用哪个方法;
- 这才是 OOP 中“多态”的核心体现。
三、运行时多态示例
// 父类
abstract class Animal {
public abstract void makeSound();
}
// 子类1
class Dog extends Animal {
@Override
public void makeSound() {
System.out.println("汪汪!");
}
}
// 子类2
class Cat extends Animal {
@Override
public void makeSound() {
System.out.println("喵喵!");
}
}
// 测试
public class Main {
public static void main(String[] args) {
Animal a1 = new Dog(); // 向上转型
Animal a2 = new Cat();
a1.makeSound(); // 输出:汪汪!
a2.makeSound(); // 输出:喵喵!
}
}
🔍 虽然
a1和a2的编译时类型都是Animal,
但它们的运行时类型分别是Dog和Cat,
因此调用的是各自重写后的方法。
四、多态的三大好处
| 好处 | 说明 |
|---|---|
| 可扩展性 | 新增子类无需修改原有代码(开闭原则) |
| 可维护性 | 逻辑集中,调用统一 |
| 解耦合 | 调用者只依赖父类/接口,不依赖具体实现 |
✅ 示例:新增动物无需改调用代码
class Duck extends Animal {
@Override
public void makeSound() {
System.out.println("嘎嘎!");
}
}
// 主程序无需修改!
Animal duck = new Duck();
duck.makeSound(); // 自动调用 Duck 的方法
五、多态中的成员访问特点
| 成员类型 | 访问规则 |
|---|---|
| 成员方法 | 运行时绑定 → 看实际对象类型(多态体现) |
| 成员变量 | 编译时绑定 → 看引用类型(无多态) |
| 静态方法 | 编译时绑定 → 看引用类型(属于类,不参与多态) |
示例说明:
class Parent {
int value = 10;
static void show() { System.out.println("Parent static"); }
void display() { System.out.println("Parent display"); }
}
class Child extends Parent {
int value = 20;
static void show() { System.out.println("Child static"); }
@Override
void display() { System.out.println("Child display"); }
}
public class Test {
public static void main(String[] args) {
Parent p = new Child();
System.out.println(p.value); // 输出:10(看引用类型)
p.show(); // 输出:Parent static(静态方法无多态)
p.display(); // 输出:Child display(方法有多态)
}
}
⚠️ 重要结论:
只有非静态的实例方法才具有多态性!
六、向下转型(Downcasting)与 instanceof
有时我们需要访问子类特有的方法,这时需将父类引用转回子类类型(向下转型):
Animal animal = new Dog();
// 安全做法:先判断类型
if (animal instanceof Dog) {
Dog dog = (Dog) animal; // 向下转型
dog.bark(); // 调用 Dog 特有方法
}
❗ 不安全的向下转型会抛出
ClassCastException!
七、多态的典型应用场景
-
接口编程(最常用)
List<String> list = new ArrayList<>(); // 面向接口编程 -
策略模式、工厂模式等设计模式
PaymentProcessor processor = factory.create("Alipay"); processor.pay(); // 不同支付方式,统一调用 -
框架回调机制(如 Spring、JUnit)
框架调用用户实现的接口方法,实现“控制反转”。
八、总结:多态的核心要点
| 关键点 | 说明 |
|---|---|
| 本质 | 同一操作作用于不同对象,产生不同行为 |
| 实现机制 | 方法重写 + 向上转型 + 动态绑定 |
| 前提 | 继承/实现 + 重写 + 父类引用指向子类对象 |
| 优势 | 提高代码扩展性、灵活性、可维护性 |
| 限制 | 仅适用于非静态、非 private、非 final 的实例方法 |
🙌 感谢你读到这里!
🔍 技术之路没有捷径,但每一次阅读、思考和实践,都在悄悄拉近你与目标的距离。
💡 如果本文对你有帮助,不妨 👍 点赞、📌 收藏、📤 分享 给更多需要的朋友!
💬 欢迎在评论区留下你的想法、疑问或建议,我会一一回复,我们一起交流、共同成长 🌿
🔔 关注我,不错过下一篇干货!我们下期再见!✨
更多推荐



所有评论(0)