




多态的核心价值是解决“新增需求必须改旧代码”问题,通过接口或父类引用调用子类重写的方法,使系统不修改原有逻辑即可接入新行为,符合开闭原则。
Java需要多态,不是为了炫技,而是为了解决真实开发中“新增需求必须改旧代码”这个高频痛点

pay() 方法?没有多态时,你大概率会写出这样的代码:
public void pay(String type, double amount) {
if ("WECHAT".equals(type)) {
// 微信逻辑
} else if ("ALIPAY".equals(type)) {
// 支付宝逻辑
} else if ("UNIONPAY".equals(type)) {
// 银联逻辑
}
}
这看似简单,但每新增一种支付方式(比如 Apple Pay),就必须打开这个方法、加 else if、重新测试全部分支——极易出错,也违反“开闭原则”。
多态把“判断类型 + 调用逻辑”这两件事拆开了:判断交给调用方(或工厂),执行交给子类。新增支付方式,只用写一个新类,实现 Payment 接口,其他地方完全不动。
if-else 或 switch 一路到底?else if,就得回归测试所有已有分支,而多态下只需测新类本身if-else 是硬编码逻辑,没法在运行时根据配置(如灰度开关)切换具体实现;多态配合 Spring 的 @Qualifier 或策略工厂,一行配置就能切实现类Java 多态背后是 JVM 的 虚方法表(vtable)+ 动态绑定:当执行 payment.pay(amount) 时,JVM 不看引用类型 Payment,而是查对象实际类型(比如 WechatPayment)的 vtable,直接跳转到该类的 pay 方法入口。这个过程在运行时完成,且高度优化——不是反射,没有性能损耗。
注意:静态方法、private 方法、final 方法不进 vtable,所以它们不参与多态。这也是为什么接口默认方法(default)可以多态,但 static 接口方法不行。
编译看左,运行也看左)this.method(),会调到子类重写版本——但此时子类字段可能还是默认值(0 / null),极易引发 NPE 或逻辑错误List 和 List 运行时都是 List,JVM 看不到泛型类型,别指望靠泛型实现运行时多态多态真正起作用的地方,永远只有一处:非静态、非私有、非 final 的实例方法调用。抓住这点,就不会在不该期待多态的地方空等结果。