抽象类结合泛型通过在类级别声明类型参数T,封装通用逻辑(如增删查),将可变行为(如排序、校验)交由子类实现,支持类型安全与可扩展性。

抽象类结合泛型,是构建可扩展、类型安全的通用数据结构的常用方式。核心在于:把类型参数声明在抽象类上,让子类继承时明确具体类型,同时把不变逻辑(如增删查、遍历、校验)统一封装,变的部分(如特定排序规则、序列化策略)留给子类实现。
抽象泛型类的基本写法
泛型参数必须定义在类级别,不能只放在方法里——否则无法约束字段和子类行为:
- 用 `abstract class Container
` 声明,T 可用于字段(private T data;)、方法参数(public void set(T item))和返回值(public T get()) - 避免使用
Object或强制转换,否则失去泛型意义 - 如果需要类型能力(比如比较),加上边界:
abstract class SortedContainer<t extends comparable>></t>
抽象方法与泛型的配合
抽象方法可以不带泛型参数,直接复用类级的 T;也可以额外声明自己的泛型方法,用于更灵活的场景:
- 常规抽象方法:
public abstract void validate(T item);—— 子类决定怎么校验该类型的数据 - 泛型方法(独立于类泛型):
public <r> R transform(Function<t r> mapper) { ... }</t></r>—— 支持任意转换逻辑,R 和 T 可不同 - 不要在抽象方法里写
if (item instanceof String)这类判断,破坏抽象性;应通过函数式接口传入策略
子类实现时的关键注意点
子类继承时需指定具体类型,或继续泛型化;两者语义不同:
立即学习“Java免费学习笔记(深入)”;
- 固定类型实现:
class IntStack extends Container<integer></integer>→ 所有方法操作Integer,适合专用结构 - 转发泛型实现:
class GenericStack<t> extends Container<t></t></t>→ 保持开放,调用方决定 T,适合通用容器 - 构造器中若需实例化元素(如初始化默认值),不能写
new T(),得传Class<t></t>或Supplier<t></t>
典型应用场景示例
比如一个支持多种存储策略的缓存抽象基类:
abstract class Cache<k v> { protected Map<k v> store; public abstract V load(K key); }</k></k>- 子类可实现
LRUCache<string user></string>或FileBackedCache<long byte></long> - 所有子类自动获得
put(K, V)、get(K)等通用方法,无需重复编码


















