You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中父类引用指向子类对象时成员变量与方法行为差异解惑

核心原因:方法动态绑定 vs 变量静态绑定

首先纠正一个理解偏差:A obj = new B();这句话的正确含义是创建一个B类的对象,但用A类型的引用变量指向它,并非“创建A类型对象并使用B的实现”,这是理解问题的关键。

接下来分两部分解释你遇到的差异:

1. 方法调用:动态绑定(多态特性)

Java中,非静态方法的调用是动态绑定的——编译阶段仅检查引用类型(此处为A)是否存在对应方法,而实际执行哪个类的方法,是在运行时根据对象的真实类型(此处为B)决定的。

在你的代码里,obj.display()的执行逻辑是:

  • 编译时确认A类有display()方法,通过编译校验;
  • 运行时JVM识别到实际对象是B,因此调用B类重写后的display()方法,自然会使用B类的z,输出B's z is 20。

2. 成员变量调用:静态绑定

和方法不同,成员变量的访问是静态绑定的——编译阶段就直接根据引用类型(此处为A)确定要访问的变量,完全不考虑运行时的真实对象类型。

B类里的int z = 20;并不是“重写”A类的z,而是隐藏了父类的z。这意味着B对象的内存中同时存在两个独立的z:一个是继承自A的z(值10),一个是B自身定义的z(值20)。当你用A类型的引用obj访问obj.z时,编译器直接绑定到A类的z,因此输出10。

如果想要访问B类的z,你可以把引用强转为B类型:

System.out.println(((B)obj).z); // 输出20

另外你也能看到,B类的display()方法里的z会直接访问自身的z,因为在类内部,默认优先访问当前类定义的成员变量(如果存在隐藏父类变量的情况)。


内容的提问来源于stack exchange,提问作者Cheesewaffle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 07:57:27