向上转型是用父类引用指向子类对象,编译时按父类检查,运行时执行子类重写方法,实现多态;字段和静态方法不具多态性;调用子类特有方法需先instanceof判断再向下转型。

父类引用指向子类对象,就是向上转型——它不是“把子类变成父类”,而是用父类这副眼镜去看一个实实在在的子类对象。编译时按父类规则检查,运行时仍执行子类的逻辑,这才是多态能“一调多效”的关键。
它到底在做什么?
代码写成 Animal a = new Dog();,JVM 做了三件事:
- 在堆上创建一个完整的 Dog 实例(含所有字段、方法表)
- 把该实例的内存地址,存进一个声明为 Animal 类型的变量 a 中
- 编译器只允许你通过 a 调用 Animal 类中定义过的方法(比如 eat()),但运行时若该方法被 Dog 重写,就自动执行 Dog 版本
为什么不能直接调子类特有方法?
因为变量 a 的类型是 Animal,编译器只认它公开的接口。比如 Dog 有 bark() 方法,但 Animal 没声明,所以 a.bark() 编译就报错。
这不是限制,而是安全设计:确保所有使用 Animal 类型的地方,都不依赖某个具体子类的细节。
字段和静态方法为什么不走多态?
字段访问和静态方法调用,只看引用类型,不看实际对象:
- Animal a = new Dog(); a.name → 访问的是 Animal 类里的 name 字段(哪怕 Dog 也定义了同名字段)
- Animal.sleep() → 调用的是 Animal 类的静态方法,不会因为右边是 Dog 就换成 Dog.sleep()
只有非静态、非 final、非 private、被重写的实例方法,才触发动态绑定。
什么时候必须向下转型?
当你确实需要调用子类特有功能时,比如让一只狗叫而不是吃:
- 先确认类型:if (a instanceof Dog)
- 再安全转换:Dog d = (Dog) a;
- 最后调用:d.bark();
跳过 instanceof 直接强转,一旦 a 实际是 Cat,运行时就会抛 ClassCastException。

















