成员变量不体现多态,因为其访问是静态绑定、编译期确定,只依据引用变量的声明类型(左边),子类同名变量仅为隐藏而非重写,不会覆盖父类变量。

Java 中多态调用时,成员变量的访问特点是:编译看左边,运行也看左边,也就是完全依据引用变量的声明类型(父类类型),而不是实际创建的对象类型(子类类型)。
为什么成员变量不体现多态?
因为成员变量没有“重写”(override)机制,只有“隐藏”(hiding)。子类中定义同名变量,只是在自己的作用域里新增了一个变量,并不会覆盖父类变量。JVM 在编译阶段就根据引用类型锁定了字段归属,运行时也不会动态切换。
- 父类引用指向子类对象时,访问变量只查父类中是否存在该字段;不存在则编译报错,不会去子类找
- 即使子类有同名变量,只要引用类型是父类,就始终读取父类中的值
- 这种行为与方法调用截然不同——方法支持动态绑定,变量不支持
典型代码表现
例如:
class Animal { int age = 40; }
class Cat extends Animal { int age = 20; }
Animal a = new Cat();
System.out.println(a.age); // 输出 40,不是 20
这里 a 的声明类型是 Animal,所以无论右边 new 的是哪个子类,a.age 永远取 Animal 类里的 age。
和成员方法的关键区别
成员方法调用是“编译看左边,运行看右边”,靠的是动态绑定和方法重写;而成员变量是静态绑定,只认声明类型:
- 方法:能体现多态,子类重写后调用的是子类逻辑
- 变量:不能体现多态,子类同名变量只是隐藏,不参与多态分派
补充说明:静态成员和实例变量一致
静态变量、静态方法的访问规则和成员变量一样——都看引用类型(左边),不是看 new 的对象。这是因为静态成员属于类本身,与对象无关,更谈不上运行时动态选择。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











