
java 向上转型(upcasting)不会改变对象的实际类型,仅限制引用可访问的成员;方法调用始终基于运行时真实对象类型,因此重写(override)的方法由子类实现执行。
在 Java 中,Mom mom = new Girl(); 是典型的向上转型(upcasting):将子类 Girl 的实例赋值给父类 Mom 类型的引用变量。这一操作合法且隐式发生,但需明确两个关键事实:
- ✅ 对象真实类型不变:new Girl() 创建的是一个 Girl 类型的实例,堆内存中存储的是完整的 Girl 对象(包括其字段、方法表等),即使引用变量声明为 Mom 类型,该对象的运行时类型(runtime type)仍是 Girl;
- ✅ 构造器调用顺序独立于引用类型:new Girl() 会先调用 Girl 的构造器(若未显式调用 super(),则默认调用 Mom() 构造器),因此你观察到 Mom 构造器被调用,是继承链初始化的正常行为,并非“创建了 Mom 实例”——它只是 Girl 实例初始化过程中对父类部分的构造。
而方法调用遵循 动态绑定(dynamic binding) 原则:编译期检查引用类型(Mom)是否声明了该方法(确保编译通过),运行期则根据实际对象类型(Girl)查找并执行最具体的重写版本。这就是 Java 多态(polymorphism)的核心机制。
以下是最小可复现示例:
class Mom {
Mom() {
System.out.println("Mom constructor called");
}
void test() {
System.out.println("Mom.test()");
}
}
class Girl extends Mom {
Girl() {
System.out.println("Girl constructor called");
}
@Override
void test() {
System.out.println("Girl.test()");
}
}
public class UpcastDemo {
public static void main(String[] args) {
Mom mom = new Girl(); // 向上转型:引用为 Mom,实例为 Girl
mom.test(); // 输出:Girl.test() ← 多态生效!
}
}输出结果:
立即学习“Java免费学习笔记(深入)”;
Mom constructor called Girl constructor called Girl.test()
⚠️ 注意事项:
- 向上转型后,只能调用 Mom 类中声明的方法或字段。若 Girl 新增了 void dance() 方法,则 mom.dance() 编译失败;
- instanceof 和向下转型(downcast)可恢复子类访问能力,但需谨慎校验类型(如 if (mom instanceof Girl) ((Girl) mom).dance(););
- static 方法和 private 方法不参与多态——它们绑定在编译时(静态绑定),调用取决于引用类型而非实际对象。
总结:向上转型 ≠ 类型转换对象,而是“以父类视角看待子类实例”。Java 的多态保障了“谁创建的,就由谁负责行为实现”,这是面向对象设计中开闭原则与可扩展性的基石。理解这一点,便不再困惑于“为何构造用父类,方法却走子类”。










