父类变量不能直接调用子类特有方法,需先用instanceof判断再向下转型;java 14+推荐模式匹配语法,java 8–13用传统转型;共性逻辑应上提至父类抽象/默认方法;高耦合场景宜改用泛型、策略或工厂模式;反射仅限框架层慎用。

父类类型变量不能直接调用子类特有方法,因为编译器只认声明类型(即父类)中定义的成员。想访问子类独有的方法,必须确认运行时对象确实是该子类实例,并显式告知编译器——也就是先判断、再转型。
必须配合 instanceof 判断再向下转型
这是最常用也最安全的做法。不加判断直接强转,一旦对象实际不是目标子类,就会抛出 ClassCastException。
- Java 14+ 推荐用模式匹配语法,简洁且空安全:
if (obj instanceof Dog d) { d.bark(); } - Java 8–13 写法:
if (obj instanceof Dog) { ((Dog) obj).bark(); }
把共性逻辑上提到父类或接口
如果多个子类都有类似行为(比如“获取信息”“生成描述”),与其每次转型调用,不如在父类中定义抽象方法或默认方法:
- 父类声明 abstract String getInfo();
- 每个子类实现自己的版本
- 外部代码统一调用 obj.getInfo(),无需知道具体类型
避免硬编码转型,考虑策略或工厂模式
当业务逻辑高度依赖子类特有行为时,说明当前用父类数组/引用统一存放可能已超出多态适用场景:
- 改用泛型容器,如 List
或 List ,从源头隔离类型 - 用工厂或策略类封装不同子类的处理逻辑,调用方只面向策略接口
- 消息路由类可结合 getType() 和 instanceof 分支处理,而不是堆砌转型代码
反射不是常规解法,慎用
虽然可通过 obj.getClass().getMethod("xxx").invoke(obj) 绕过编译检查,但牺牲了类型安全、可读性和性能:
- 方法名写错或参数不匹配会在运行时报错,IDE 无法提示
- 破坏封装,绕过访问控制(如 private 方法)易引发维护问题
- 仅建议用于框架层或极少数动态扩展场景,业务代码中应避免










