子类强转为父类后访问同名属性获取的是父类的值,因为java中成员变量访问基于编译时类型静态绑定,子类同名字段会隐藏而非覆盖父类字段,两者在内存中独立存储。

子类强转为父类后,访问同名属性获取的是父类的值,不是子类的。
属性访问看“左边类型”,不看实际对象
Java 中成员变量(属性)没有多态性,访问时完全取决于引用变量的声明类型,也就是等号左边的类型。这叫“静态绑定”或“编译时绑定”。
- Fu f = new Zi();
即使f实际指向的是子类对象,只要声明类型是Fu,那么f.name就访问Fu类中定义的name属性。 - 哪怕子类
Zi也定义了同名属性name,它和父类的name是两个独立字段,内存中各自存在,互不影响。 - 这种现象叫“属性隐藏”,不是“重写”。隐藏只影响直接通过引用访问字段的行为,不影响方法调用。
子类中有同名属性时,实际发生了什么
当子类定义了与父类同名的实例变量:
- 子类对象内存中会同时存在两份字段:一份来自父类(通过继承),一份是子类自己声明的。
-
new Zi()创建的对象,既包含Fu.name,也包含Zi.name—— 它们地址不同、值可不同。 - 用
z.name(z是Zi类型引用)访问的是子类自己的name;
用f.name(f是Fu类型引用)访问的是父类的name。
想在子类里明确访问父类同名属性?用 super
如果子类方法中需要读取或修改父类那份字段,必须显式使用 super.name:
-
this.name→ 当前类(子类)定义的字段 -
super.name→ 父类定义的字段(即使子类有同名字段也不影响) - 注意:
super只能在非静态方法/构造器中使用,不能在静态上下文中出现。
对比方法调用:方法才有多态,属性没有
这是关键区别:
- 方法调用走的是“运行时绑定”:
f.show()即使f是Fu类型,只要实际是Zi对象且show()被重写,就执行子类版本。 - 属性访问走的是“编译时绑定”:
f.name的行为在编译阶段就定死了,只认Fu类有没有这个字段,不查实际对象是谁。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











