Java中利用多态处理不同子类集合的核心是用父类或接口类型统一管理子类对象,使集合不关心具体实现而只依赖共同行为,从而提升灵活性与可扩展性。

用父类/接口类型声明集合
声明集合时,别用具体实现类(如 ArrayList 或 HashSet)作变量类型,而要用它的上层接口或抽象父类:
- List<Animal> animals = new ArrayList<>(); —— 存的是 Animal 的子类(Dog、Cat 等),不是 Animal 本身
- Collection<Drawable> shapes = new LinkedList<>(); —— Drawable 是接口,Circle、Rectangle 都可加入
- 这样后续替换底层实现(比如从 ArrayList 换成 LinkedList)或添加新子类(比如新增 Bird 类),都不影响集合操作逻辑
遍历时自动调用各自重写的方法
只要子类重写了父类或接口中定义的方法,遍历集合时就会自动执行对应子类的版本:
- 假设 Animal 有 public void move(),Dog 和 Cat 分别重写为“奔跑”和“轻跳”
- for (Animal a : animals) { a.move(); } —— 不用 if-else 判断类型,每调一次就按实际对象执行对应逻辑
- 这种写法把差异封装在子类内部,集合层保持干净、可读性强
方法参数接收多种子类集合
把集合作为参数传入方法时,也应使用顶层接口类型,而不是具体实现:
- void process(Collection<? extends Shape> shapes) —— 可接收 List<Circle>、Set<Rectangle> 等任意子类集合
- void printAll(List<Animal> list) —— 传入 ArrayList<Dog> 或 LinkedList<Cat> 都合法
- 编译器只检查是否符合类型约束,运行时由 JVM 动态绑定到实际对象的方法
配合工具类和泛型进一步通用化
Java 集合工具类(如 Collections)和泛型设计本身就基于多态思想:
立即学习“Java免费学习笔记(深入)”;
- Collections.sort(list) 要求 list 元素实现 Comparable,不管它是 String、Integer 还是自定义的 Person
- Stream<T> 操作(如 map、filter)对任何 T 的子类集合都适用,只要泛型约束一致
- 泛型擦除后仍保留运行时类型信息,保证多态行为不丢失


















