核心是方法参数应声明为父类或接口类型,子类对象可直接传入并自动调用重写方法,新增子类时调用方和逻辑层零修改;需满足非private/static/final、@Override重写、父类引用调用三条件;集合批量操作天然适配;优先用接口定义行为契约。

核心就一条:方法参数声明成父类或接口类型,子类对象直接传进去,运行时自动走各自重写的方法——不用改方法签名,也不用在方法里判断类型。
形参用父类或接口,不是为了“显摆多态”,而是为了不改代码
比如有个支付处理方法:
-
正确写法:
void process(PaymentProcessor p),后续加支付宝、微信、PayPal实现类,这个方法一行都不用动 -
错误写法:
void process(AlipayProcessor p),一加新支付方式就得重载或改参数类型,违背开闭原则
关键不在“能不能多态”,而在于“新增子类时,调用方和逻辑层是否零修改”。
子类必须重写父类中被调用的方法
父类方法要能被动态分发,得满足三个条件:
- 不能是
private、static或final - 子类用
@Override显式重写(编译器可校验) - 调用发生在父类引用上,例如
animal.makeSound(),不是((Dog) animal).bark()
像 Dog.makeSound() 输出 "Woof!",Cat.makeSound() 输出 "Meow!",调用方只写一次 feed(animal) 就能自动区分。
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
集合场景下更直观,也更常用
批量操作天然适合多态参数:
-
void batchFeed(List可接收animals) Arrays.asList(new Dog(), new Cat(), new Bird()) -
void saveAll(Collection能同时存users) Admin、Guest、Member,只要它们都继承User或实现同一接口
注意:如果 Guest 没继承 User 也没实现对应接口,编译直接报错,Java 不做隐式向上转型。
优先选接口,而不是抽象类
定义行为契约时,接口更干净:
- 一个类可以实现多个接口(如
Runnable & Serializable & Cloneable),但只能继承一个类 - 接口不带字段和默认逻辑,避免把“可能用到”的方法塞进父类,导致语义模糊
- 只有当多个实现需要共享字段(如通用ID)、基础校验逻辑或模板方法时,才考虑抽象父类
例如:日志、通知、导出等能力,分别定义 Logger、Notifier、Exporter 接口,比塞进一个大而全的 BaseService 更清晰。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










