在 Java 中,多态 主要体现在方法 上,而属性(成员变量)不具有多态性。这是 Java 多态机制的核心规则之一。
多态中方法的行为
-
方法调用遵循"编译看左边,运行看右边"原则:
- 编译阶段:检查父类引用是否声明了该方法。
- 运行阶段 :实际调用的是子类重写后的方法(如果子类重写了该方法)。
-
前提条件:
- 存在继承关系(子类继承父类或实现接口)。
- 子类重写(override)父类方法。
- 使用父类引用指向子类对象(向上转型)。
-
示例:
class Animal {
void eat() {
System.out.println("动物吃东西");
}
}class Dog extends Animal {
@Override
void eat() {
System.out.println("狗吃骨头");
}
}public class Test {
public static void main(String[] args) {
Animal a = new Dog(); // 向上转型
a.eat(); // 输出:狗吃骨头(运行时调用子类重写的方法)
}
}
多态中属性的行为
-
**属性访问始终"编译看左边,运行也看左边"**:
- 无论实际对象是哪个子类,访问的是父类引用类型中定义的属性。
- 属性不会被重写,子类中同名属性只是"隐藏"了父类属性,而非覆盖。
-
示例:
class Parent {
int value = 10;
}class Child extends Parent {
int value = 20; // 隐藏父类属性,不是重写
}public class Test {
public static void main(String[] args) {
Parent p = new Child();
System.out.println(p.value); // 输出:10(父类的 value)
}
}
其他不具有多态性的成员
以下成员不支持多态,编译期就确定调用哪个版本:
- 静态方法 (
static):调用取决于引用类型。 - 私有方法 (
private):不能被子类重写。 - **
final方法**:不能被重写。 - 构造方法:不属于继承体系,不参与多态。
**示例:**静态方法无多态
class A { static void show() { System.out.println("A"); } }
class B extends A { static void show() { System.out.println("B"); } }
A a = new B();
a.show(); // 输出 "A",不是 "B"
备注
- 方法 :多态 → 运行时动态绑定,调用子类重写的方法。
- 属性 :无多态 → 始终访问父类引用中的属性。
- 注意:若需访问子类特有属性或方法,必须进行向下转型 ,并使用
instanceof安全判断。