抽象类的核心是定义契约、约束行为、延迟实现,通过声明抽象方法、封装固定流程和提供可复用能力,使子类专注差异化逻辑,上层代码面向抽象编程,配合模板方法确保流程统一与扩展安全。
抽象类作为多态引用的父级入口,核心在于**定义契约、约束行为、延迟实现**。它不提供完整逻辑,但强制子类遵循统一接口和基础结构,让上层代码能以“父类类型”安全地调用不同子类的具体行为。
定义抽象类:声明共性 + 留出可变点
把所有子类必然具备的属性、公共方法(含默认实现)和必须重写的逻辑,用
abstract
明确区隔:
用
public abstract 方法()
声明子类必须实现的行为(如
、
)
用
public final 方法()
封装不可变流程(如模板方法中固定调用顺序)
用
protected 字段或普通方法
提供子类可复用的基础能力(如日志工具、配置读取)
子类继承并实现:只专注差异化逻辑
子类只需实现抽象方法,无需关心调用时机或上下文——这些由抽象父类控制:
避免重复写初始化、校验、包装等样板代码
每个子类只回答“我怎么算”“我怎么画”“我怎么验证”,不回答“什么时候算”“谁来触发”
例如:
实现
为生成 PDF;
同样继承,只改写 export 为生成 Excel
上层代码面向抽象编程:用父类类型持有、调用
业务逻辑中声明变量、参数、返回值都用抽象类类型,运行时绑定具体子类实例:
工厂方法、策略选择、配置驱动等场景,返回
而非具体类型
新增子类(如
)完全不影响原有调用方代码
配合模板方法模式强化规范性
在抽象类中定义算法骨架,把可变步骤设为 abstract,确保流程一致、行为可控:
其中
和
是 abstract,子类必须实现;其余是固定逻辑
既统一了执行顺序,又允许各环节定制,比纯接口更有力约束过程
不复杂但容易忽略的是:抽象类不是为了“看起来高级”,而是为了让变化集中、扩展安全、协作清晰。只要契约稳定,下层怎么实现,上层不必知道;上层怎么用,下层也不必操心。
calculatePrice()render()PDFReport extends Reportexport()ExcelReportReport report = new PDFReport(); report.export();ReportHTMLReportpublic final void generate() { validate(); prepareData(); export(); logSuccess(); }validate()export()