抽象类通过继承定义骨架、组合引入能力,实现复用与解耦;模板方法模式协调二者协作;应避免继承滥用,优先采用组合优先策略。

抽象类本身不直接“做”组合,但它能和组合、继承协同工作,让代码复用更清晰、更安全、更可控。关键不是单独用抽象类,而是把它放在合理的结构里:用继承定义骨架,用组合引入能力,两者分工明确。
抽象类 + 继承:统一变化点,复用稳定逻辑
抽象类适合封装多个子类共有的字段、构造逻辑和通用方法,同时强制子类实现差异化行为。这样,新增子类时不用重复写初始化、校验、日志等稳定逻辑。
- 比如 Shape 抽象类定义
color、x、y和moveTo()方法,所有图形子类自动获得移动能力 - 子类只需重写
draw(),不用再管坐标更新或颜色管理 - 新增 Triangle 类时,继承
Shape并实现draw(),就能接入已有渲染流程
抽象类 + 组合:解耦可变依赖,避免继承污染
当某个能力不属于“is-a”关系,但又需要被多个子类复用时,不要强行塞进继承链——改用组合。抽象类可以持有接口或具体类的引用,把行为委托出去。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 例如 PaymentProcessor 是抽象类,它不自己处理支付,而是组合一个
PaymentGateway接口 - 子类如
WechatPayProcessor和AlipayProcessor在构造时注入不同网关实例 - 这样支付逻辑可独立演进,抽象类只负责统一流程(如风控检查、结果回调),不绑定具体实现
模板方法模式:抽象类驱动组合与继承协作
这是抽象类发挥复用价值的经典方式:在模板方法中调用抽象方法(留给子类实现)+ 调用组合对象的方法(复用外部能力)。
- 抽象类 Game 定义
play()模板方法,内含initialize()(抽象)、start()(抽象)、logResult(new GameLogger())(组合) - 子类只关注游戏规则,日志、监控、存档等横切能力由组合对象提供
- 复用率提升来自两层:子类复用模板流程;所有子类共享同一套日志组件
避免滥用继承,优先让抽象类“组合优先”
抽象类不是继承的终点,而是协调中心。如果发现子类开始重写大量父类方法、或频繁出现 if-else 判断类型来决定是否调用某功能,说明该功能本不该属于继承体系——应提取为组合组件。
- 比如原本在
Document抽象类里硬编码 PDF 导出逻辑,后来要支持 Word、Markdown,就该把导出能力拆成Exporter接口,由抽象类组合持有 - 子类构造时传入对应导出器,而不是靠继承“背”下所有格式支持
- 这样新增格式只需加个新实现类,不碰抽象类和任何子类
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










