接口与抽象类结合泛型实现通用契约定义,核心是分层协作:接口用泛型声明行为契约,抽象类用泛型提供骨架实现,两者共同保证类型安全、行为一致、扩展自由。

泛型接口定义统一行为契约
接口负责回答“能做什么”,必须用泛型参数明确数据边界,避免类型擦除后退化为 Object:
- 声明泛型接口时,类型参数(如 T)需出现在所有关键方法签名中,例如:void handle(T event)、T generateResult()、List<T> batchProcess(List<? extends T> inputs)
- 不写泛型的接口(如 IDispatcher)会导致实现类重写方法时签名不匹配,编译报错
- 每个具体业务绑定一个类型,如 OrderDispatcher implements IDispatcher<OrderCreatedEvent>,既可多态调用,又保有编译期类型检查
泛型抽象类封装共用流程与状态
抽象类负责回答“怎么部分做”,它继承泛型接口,并携带相同类型参数,复用逻辑、共享字段、预留钩子:
- 声明为 abstract class BaseDispatcher<T> implements IDispatcher<T>,确保类型参数传递不丢失
- 在其中实现公共步骤:日志记录、幂等校验、结果包装;把差异点设为 protected abstract 方法,如 doHandle(T event)
- 可持有泛型相关的成员变量,如 protected final Class<T> eventType;,用于运行时类型识别
组合使用支撑策略式分发
真实业务中,接口+抽象类+泛型三者配合策略容器,形成可插拔的通用分发体系:
- 注册中心用 Map<String, IDispatcher<?>> 存储不同业务分发器,靠 getBusinessType() 路由,类型擦除不影响调用安全
- 调用方只依赖 IDispatcher<T> 接口,传入具体事件对象,编译器自动推导 T,无需强转
- 新增业务只需继承 BaseDispatcher<NewEvent>,实现抽象方法,注册进 Map,零侵入扩展
注意泛型边界与设计意图的匹配
泛型不是装饰,要服务于契约清晰性:
立即学习“Java免费学习笔记(深入)”;
- 接口中的 default 方法仅适合无状态逻辑(如空值判断),复杂流程仍应放在抽象类里
- 若需构造器注入或初始化资源,必须用抽象类——接口不能声明构造方法
- 当多个实现类需要共享状态(如缓存、配置、连接池),抽象类比接口更合适;若只是能力声明(如可序列化、可导出),优先用接口


















