多态是Java实现开闭原则最自然的方式,关键在于调用方依赖抽象、运行时动态绑定;通过接口定义契约、工厂创建实例、客户端仅操作接口类型,新增功能无需修改原有代码。

多态是 Java 中落地开闭原则最自然、最常用的方式。它不靠改老代码来加新功能,而是让新类“插得进去、替得出来”。关键不在有没有继承或实现接口,而在于调用方是否真正依赖抽象,运行时是否能自动切换行为。
用接口定义统一契约,把变化关进多态的笼子
接口只声明能力,不带状态、不写实现,天然适合隔离变化。比如通知服务:
- 定义 Notifier 接口,只含
send(String content) - 微信、短信、邮件各自实现该接口,互不干扰
- 业务类如
OrderService只持有Notifier引用,调用send()即可 - 要加站内信?新增
InternalNotifier类实现接口,其他代码一行不动
运行时绑定才是多态生效的前提
如果还在方法里写 new SmsNotifier() 或用 if (type == "sms") 判断,多态就形同虚设——扩展时仍得改调用逻辑。
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 对象创建应交给工厂类或 Spring 容器,比如传入配置项
"wechat",返回对应实例 - 客户端代码永远只操作接口类型,具体是谁干活,由实际传入的对象决定
- 测试时可轻松注入 Mock 实现,不依赖真实渠道
优先选接口,慎用抽象类
接口更轻量、更安全:没有字段、没有默认实现,每个实现类必须明确表达自己怎么做事。
立即学习“Java免费学习笔记(深入)”;
- 抽象类容易悄悄引入共享状态或默认逻辑,新子类可能无意中被旧行为拖累
- 若真要用抽象类,只放稳定骨架,可变部分全用
abstract方法留空 - 例如日志模板:
log()是 final 流程,doLog()必须子类重写
一眼识别 OCP 是否被破坏
不用看设计文档,翻代码就能判断:
- 方法里出现
if (type.equals("xxx"))或新增case?违反 OCP - 修改
process()方法体来支持新类型?违反 OCP - 参数里带
PaymentType type,再用分支分发?坏味道 - 正确做法是:由子类各自实现
process(),调用方无感知

















