接口定义能力契约,抽象类提供通用实现与强制约束;如Flink中StreamOperator接口声明生命周期,AbstractStreamOperator抽象类封装共用字段并留钩子,StreamMap类通过继承+实现双重角色确保类型安全与复用。

接口与抽象类在开源框架中不是孤立存在的,而是协同构建分层契约与可扩展实现的关键组合。分析源码时,重点看它们如何分工:接口定义“能做什么”,抽象类解决“怎么复用”和“哪些必须做”。
看接口——抓能力契约与组合逻辑
以 Flink 的 StreamOperator 为例:
- 顶层
StreamOperator<OUT>接口只声明生命周期(open()/close())和容错方法(snapshotState()),不涉及数据处理细节,纯粹是运行时契约 -
OneInputStreamOperator<IN, OUT>和TwoInputStreamOperator<IN1, IN2, OUT>是能力接口,通过extends StreamOperator组合基础契约,再各自声明输入处理行为 - 这种设计让一个算子类可以同时满足“有生命周期”+“支持单输入”+“支持状态快照”等多个正交能力,靠的是接口继承与实现,而非强耦合的类继承
看抽象类——找通用实现与强制约束点
继续看 Flink 的 AbstractStreamOperator:
- 它实现了
StreamOperator接口,但本身是abstract类,意味着不能直接 new,必须由子类继承 - 它封装了所有算子共有的字段:
StreamConfig、Output<StreamRecord<OUT>>、StreamingRuntimeContext,避免每个具体算子重复声明 - 它提供了默认的空实现(如
snapshotState()默认不做任何事),也留出钩子方法(如setup())供子类定制,体现“约定优于配置”
看具体类——理清“接口实现 + 抽象类继承”的双重角色
比如 StreamMap 类的声明是:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
立即学习“Java免费学习笔记(深入)”;
public class StreamMap<IN, OUT> extends AbstractUdfStreamOperator<OUT> implements OneInputStreamOperator<IN, OUT>
这说明它:
- 继承
AbstractUdfStreamOperator(抽象类),获得用户函数管理、序列化支持等通用能力 - 实现
OneInputStreamOperator(接口),承诺提供processElement()方法,明确自己只处理单路流 - 没有实现
TwoInputStreamOperator,所以编译器会阻止它被误用于双流 Join 场景——类型安全由接口边界保障
对比 Java I/O 框架中的 FilterReader
再看 JDK 自带的 FilterReader:
- 它是
abstract class,继承自Reader(抽象类),又持有一个Reader in成员——这是装饰器模式的典型结构 - 它不定义新能力接口,而是复用
Reader的read()、close()等方法签名,把“增强读取行为”的职责留给子类(如BufferedReader重写readLine()) - 这里接口(
Reader)划定了字符流的基本行为边界,抽象类(FilterReader)提供了装饰骨架,具体类完成功能拼装

















