Java子类型化继承引发意外输出,求解析变量隐藏与方法重写逻辑
Java变量隐藏与方法重写的核心原理解析
未重写m()方法时的输出逻辑
当你调用sub.m()时,由于Sub类没有重写m(),实际执行的是父类Super中定义的m()方法(Java的方法调用是动态绑定,但这里子类继承了父类的方法,所以执行父类的实现)。
在Super的m()方法里,System.out.println(i)中的i是静态绑定到Super类的实例变量的。Java对变量的访问规则是:编译器会根据方法所在的类(这里是Super)来确定要访问的变量,完全不考虑运行时this的实际类型(哪怕this指向Sub实例)。
子类Sub中的i只是**隐藏(shadowing)**了父类的同名变量,并非覆盖——两个变量是独立存在的,各自属于Super和Sub的实例空间。父类的方法只能看到自己类中定义的i,所以输出Variable of superclass。
重写m()方法后的输出变化
当你取消Sub类中m()方法的注释后,Sub重写了Super的m()方法。此时调用sub.m()会执行Sub类中的m()实现。
在Sub的m()方法里,System.out.println(i)中的i会被静态绑定到Sub类的实例变量。因为现在方法定义在Sub类中,编译器会解析为访问Sub的i,所以输出Variable of subclass。
关键结论
- 方法调用:动态绑定,由运行时实例的实际类型决定执行哪个方法。
- 变量访问:静态绑定,由代码所在的类决定访问哪个变量,与运行时实例类型无关。
- 子类同名变量只是隐藏父类变量,二者共存,可通过
super.i在子类中显式访问父类变量。
内容的提问来源于stack exchange,提问作者Jan
相关产品推荐
相关产品推荐

