抽象类在通用组件开发中核心是划清边界、统一能力、复用逻辑,通过abstract方法强制子类实现契约,封装共享状态与流程,构造器强制注入依赖,并规避滥用风险。

抽象类在通用组件开发中,核心是划清边界、统一能力、复用逻辑,而不是为了继承而写父类。它让组件可插拔、可验证、可演进。
强制子类实现关键能力契约
通过 abstract 方法明确组件必须提供的行为,编译期就能拦截缺失实现。
- 比如定义 AbstractDataSource,声明
connect()和executeQuery(String)为抽象方法,MySQLComponent、RedisComponent 就必须提供具体实现,否则编译失败 - 若某子类真无法实现某个抽象方法,说明契约设计过重,应拆分层级——例如把连接相关方法抽到更基础的 AbstractConnector 中
- IDE 自动生成实现时,需立刻检查方法体是否为空或仅含
throw new UnsupportedOperationException()
封装跨组件共享状态与流程
接口无法持有字段或复用逻辑,而抽象类天然支持 protected 字段 + 具体方法,适合承载共性上下文。
- 在抽象类中定义
protected final Config config或private int maxRetries,避免各子类重复声明 - 用模板方法组织稳定流程:如
public final void fetch() { before(); doFetch(); after(); },其中doFetch()抽象,before()和after()提供默认实现(如埋点、日志、资源清理) - 子类覆写
before()时,若需保留父类逻辑,必须显式调用super.before()
通过构造器强制注入核心依赖
抽象类不提供无参构造器,子类就必须通过 super(...) 传入必要组件,从源头保障初始化完整性。
- 只声明带参构造器:
protected AbstractProcessor(DataSource ds, MetricsReporter reporter) - 构造器内立即校验非空:
if (ds == null) throw new IllegalArgumentException("ds is required") - 初始化
final字段(如private final DataSource ds),确保不可变、线程安全 - 关键组件暴露为
protected final或提供protected DataSource getDataSource(),不 public、不 private
规避常见落地风险
抽象类一旦滥用,组件体系会迅速僵化。几个关键点必须守住:
- 不在构造器中调用抽象方法——子类字段尚未初始化,极易 NPE;运行时定制行为应留在模板方法中
- 不硬编码配置值(如数据库 URL、超时时间),全部通过构造参数或 setter 注入,保持子类定制自由度
- 不把抽象类写成 static 工具集合——塞满静态方法会削弱继承语义,也妨碍单元测试 mock
- 不依赖接口 default 方法替代抽象方法——抽象类不支持 default,写了直接编译报错










