Java变量隐藏疑问:子类调用继承方法为何输出父类变量值?
为什么Mouse调用getRodentDetails()输出的是4而不是8?
嘿,这个问题刚好踩中了Java里很多新手容易搞混的一个点——成员变量的「隐藏」和方法的「重写」是完全两套不同的机制!咱们一步步拆解:
首先看你的代码:
- 父类
Rodent定义了protected int tailLength = 4,还有一个getRodentDetails()方法输出this.tailLength - 子类
Mouse定义了同名的protected int tailLength = 8,但没有重写父类的getRodentDetails()方法
核心原因:成员变量是「静态绑定」,方法是「动态绑定」
当你用Mouse对象调用继承来的getRodentDetails()时,这个方法的代码还是父类Rodent里的实现。在这个方法里,this.tailLength的访问规则是:
成员变量的引用是编译时确定的,它只看当前方法所属的类(也就是
Rodent),而不管运行时this实际指向的是哪个子类对象。
简单说:虽然this在运行时确实是Mouse实例,但父类方法里访问tailLength时,编译器会直接绑定到父类的tailLength变量,所以输出4。
对比一下方法重写的情况
如果我们在Mouse里重写getRodentDetails():
public class Mouse extends Rodent { protected int tailLength = 8; @Override public void getRodentDetails() { System.out.println(this.tailLength); } public static void main(String[] args) { Mouse mouse = new Mouse(); mouse.getRodentDetails(); // 这时候会输出8 } }
这时候因为方法是动态绑定的,运行时会调用子类的实现,子类方法里的this.tailLength就会绑定到子类的变量,输出8。
再补个关键知识点
Java里只有方法支持「动态绑定」(也就是多态),成员变量、静态方法、私有方法都是「静态绑定」的——编译时就确定了要访问的是哪个类的成员。所以子类同名变量只是把父类的变量「隐藏」了,而不是「覆盖」,父类的方法依然会访问自己的变量。
内容的提问来源于stack exchange,提问作者Number945
相关产品推荐
相关产品推荐

