如何通过抽象类构建系统框架,确保子类实现特定功能?
- 内容介绍
- 相关推荐
本文共计775个文字,预计阅读时间需要4分钟。
抽象类是一种定义系统骨架行为的有力工具,它将通用逻辑和流程控制放置在父类中,同时使用留空关键字的关键环节。这种设计确保了整体结构的统一性,同时保留了子类的灵活性。
用抽象类封装不变流程,抽出可变部分
系统中常有一些固定执行顺序(比如:初始化 → 处理 → 清理),但每一步的具体操作因场景而异。抽象类适合把流程骨架写死,把变化点声明为 abstract 方法。
- 在抽象类中用普通方法编写完整流程(如 execute()),内部调用若干 abstract 方法
- 这些 abstract 方法不写实现,只定义签名,子类必须重写它们
- 子类无法绕过流程——只要调用 execute(),就必然经过预设步骤
抽象方法 + 模板方法 = 可控的扩展点
模板方法模式是抽象类最典型的用法。父类定义算法骨架,子类只负责填空,不改变流程本身。
- 例如日志处理器:log(String msg) 是模板方法,内部依次调用 beforeLog()、doLog()、afterLog()
- 其中 doLog() 声明为 abstract,子类必须实现(如写文件、发网络请求、存数据库)
- beforeLog() 和 afterLog() 可以有默认实现(如加时间戳、释放资源),子类按需重写
结合具体方法与抽象方法,平衡复用与约束
抽象类不是只写 abstract 方法。合理混用具体方法、final 方法和 abstract 方法,能精准控制子类自由度。
- 核心算法步骤用 abstract 强制实现
- 通用工具逻辑(如参数校验、格式转换)写成 protected 具体方法,供子类直接复用
- 关键流程节点用 final 修饰(如 execute()),防止子类覆盖整个流程
- 避免在抽象类构造器中调用 abstract 方法——子类对象尚未初始化完成,易出错
注意抽象类与接口的分工
抽象类侧重“是什么 + 怎么做一部分”,接口侧重“能做什么”。当需要共享状态、复用代码、或定义严格流程时,优先选抽象类。
- 如果多个子类有共同字段(如连接池、配置对象),抽象类可直接定义并初始化
- 若只是行为契约且无共用逻辑,接口更轻量、支持多实现
- JDK 8+ 接口可有 default 方法,但不能有构造器、不能存状态——这是抽象类不可替代的地方
本文共计775个文字,预计阅读时间需要4分钟。
抽象类是一种定义系统骨架行为的有力工具,它将通用逻辑和流程控制放置在父类中,同时使用留空关键字的关键环节。这种设计确保了整体结构的统一性,同时保留了子类的灵活性。
用抽象类封装不变流程,抽出可变部分
系统中常有一些固定执行顺序(比如:初始化 → 处理 → 清理),但每一步的具体操作因场景而异。抽象类适合把流程骨架写死,把变化点声明为 abstract 方法。
- 在抽象类中用普通方法编写完整流程(如 execute()),内部调用若干 abstract 方法
- 这些 abstract 方法不写实现,只定义签名,子类必须重写它们
- 子类无法绕过流程——只要调用 execute(),就必然经过预设步骤
抽象方法 + 模板方法 = 可控的扩展点
模板方法模式是抽象类最典型的用法。父类定义算法骨架,子类只负责填空,不改变流程本身。
- 例如日志处理器:log(String msg) 是模板方法,内部依次调用 beforeLog()、doLog()、afterLog()
- 其中 doLog() 声明为 abstract,子类必须实现(如写文件、发网络请求、存数据库)
- beforeLog() 和 afterLog() 可以有默认实现(如加时间戳、释放资源),子类按需重写
结合具体方法与抽象方法,平衡复用与约束
抽象类不是只写 abstract 方法。合理混用具体方法、final 方法和 abstract 方法,能精准控制子类自由度。
- 核心算法步骤用 abstract 强制实现
- 通用工具逻辑(如参数校验、格式转换)写成 protected 具体方法,供子类直接复用
- 关键流程节点用 final 修饰(如 execute()),防止子类覆盖整个流程
- 避免在抽象类构造器中调用 abstract 方法——子类对象尚未初始化完成,易出错
注意抽象类与接口的分工
抽象类侧重“是什么 + 怎么做一部分”,接口侧重“能做什么”。当需要共享状态、复用代码、或定义严格流程时,优先选抽象类。
- 如果多个子类有共同字段(如连接池、配置对象),抽象类可直接定义并初始化
- 若只是行为契约且无共用逻辑,接口更轻量、支持多实现
- JDK 8+ 接口可有 default 方法,但不能有构造器、不能存状态——这是抽象类不可替代的地方

