多态数组和集合的核心价值是用统一类型容器管理多种子类实例,关键在安全调用:数组需instanceof校验后转型;泛型集合增强类型安全但调用子类特有方法仍需转型或钩子设计;真正解耦应通过策略模式+工厂模式替代硬编码判断。

多态数组和集合的核心价值,是用统一类型容器管理多种子类实例,让业务逻辑不随类型增加而反复修改。关键不在“存”,而在“如何安全调用”。
多态数组:编译期类型固定,运行时行为动态
声明 Parent[] arr = new Parent[3] 后,可存入 new ChildA()、new ChildB() 等任意子类对象。但注意:
- 数组元素的静态类型始终是 Parent,只能直接调用 Parent 中定义的方法或被子类重写的方法
- 若需访问子类特有方法(如 ChildB.doSpecial()),必须先用 instanceof 判断,再强制向下转型:(ChildB) arr[i]
- 转型前未校验类型会抛出 ClassCastException,所以 instanceof 不是可选项,而是必选项
泛型集合:类型安全更进一步,但仍有边界
用 List
- 添加时自动检查,list.add(new ChildA()) 合法,list.add("hello") 编译失败
- 遍历时仍不能直接调用子类独有方法,原因同数组:变量声明类型是 Parent
- 若需差异化处理,推荐在父类中预留钩子方法(如 process()),由各子类按需实现,而非频繁转型
真正解耦:用策略+工厂代替硬编码判断
当集合中子类越来越多,满屏 if (x instanceof A) {...} else if (x instanceof B) {...} 就成了技术债。更优路径是:
- 定义统一接口或抽象类,把差异行为抽象为方法(如 execute()、render())
- 每个子类专注实现自身逻辑,不暴露内部结构
- 配合简单工厂或配置驱动(如根据 type 字段查 Map
),让新增类型只需加类+注册,不碰原有调度代码
实际踩坑提醒
常见误区包括:
- 误以为 Parent p = new Child(); p.field 会取子类字段值——实际取的是 Parent 中定义的同名字段(成员变量不具多态性)
- 在循环中反复做 instanceof + cast,却没提取共性到父类,导致维护成本飙升
- 用 Object[] 存各种对象,失去类型约束,等于放弃编译期保护










