父类引用指向子类对象是Java多态的核心机制,即用父类类型声明变量但实际指向子类实例,实现编译期看父类、运行期看子类的动态绑定。

这是Java中实现多态的核心机制:用父类类型声明变量,但实际指向一个子类创建的对象。它不是类型转换,而是一种“向上转型”(upcasting),是安全且自动发生的。
什么是父类引用指向子类对象
指用父类的变量名,去接收子类 new 出来的实例。例如:
Animal a = new Dog(); —— Animal 是父类,Dog 是子类,a 是父类引用,但它指向的是 Dog 对象。
此时 a 只能调用 Animal 中定义的方法和属性(编译期看左边),但若调用的是被子类重写(override)的方法,则运行时执行子类版本(运行期看右边)——这就是“动态绑定”或“后期绑定”。
立即学习“Java免费学习笔记(深入)”;
为什么允许这样做
因为子类是父类的“加强版”,满足“is-a”关系(Dog is-an Animal),所有父类能做的事,子类都能做(可能还更多)。所以把子类对象赋给父类引用,不会破坏类型安全性。
这种设计让代码更灵活、可扩展。比如方法参数写成父类类型,就能接收任意子类对象,无需为每个子类单独写方法。
能做什么、不能做什么
能做的:
- 调用父类中声明的方法(包括被子类重写的方法,运行时走子类逻辑)
- 访问父类中可见的字段(注意:字段不支持多态,访问的是父类中的字段,不是子类的同名字段)
- 作为参数传入接受父类类型的方法
- 放入父类类型的集合(如 List
)
不能做的:
- 直接调用子类独有的方法(如 a.bark() 报错,因为编译器只认 Animal 类型)
- 直接访问子类独有的字段(同理,编译不通过)
- 不做强制类型转换,就无法当子类用
如何安全使用子类特有功能
如果确实需要调用子类独有方法,需先判断再转型:
if (a instanceof Dog) {
Dog d = (Dog) a;
d.bark(); // OK
}
推荐用 instanceof 防止 ClassCastException;Java 14+ 也可用模式匹配简化:if (a instanceof Dog d) { d.bark(); }。
不复杂但容易忽略:父类引用指向子类对象,本质是“编译看声明,运行看实际”,它让接口统一、行为可变,是面向对象灵活性的关键体现。










