Java向上转型行为疑问:属性与方法调用结果为何不同?
Java向上转型中属性与方法的行为差异解释
你的疑惑核心在于Java中属性的编译期绑定和方法的运行期动态绑定的区别,结合你的代码逐一拆解:
代码回顾
public class Main { public static void main(String[] args) { A x = new B(); System.out.println(x.i); System.out.println(x.shout()); } } class A{ int i = 10; int shout(){ return i; } } class B extends A{ int i = 20; int shout(){ return i; } }
输出结果:
10 20
关键逻辑解析
1. 直接访问属性x.i的行为
执行A x = new B()时,变量x的编译类型是父类A,但实际运行的对象是子类B。不过Java中属性的访问是编译期确定的:编译器只会根据变量的编译类型(A)查找对应属性,因此直接取A类定义的i=10。
子类B中int i=20不是重写父类属性,而是**隐藏(Hiding)**了父类的同名属性——相当于在B类中创建了一个全新的、和父类A的i无关的变量,只是名字相同而已。
2. 调用方法x.shout()的行为
方法调用遵循运行期动态绑定规则:编译器先检查变量的编译类型(A)是否包含该方法(A确实有shout()),程序运行时则根据对象的实际类型(B)选择执行的方法。
由于子类B重写(Override)了父类A的shout()方法,运行时会执行B类的shout(),返回B类自己的i=20。
补充:访问子类属性的方式
如果要获取子类B的i,需要将x强制转型为B类型:
System.out.println(((B)x).i); // 输出20
内容的提问来源于stack exchange,提问作者Ajinkya Ronghe
相关产品推荐
相关产品推荐

