贝利信息

Java继承与多态的语法基础

日期:2026-01-11 00:00 / 作者:P粉602998670
Java类单继承且不可继承final类;私有成员存在但不可见;@Override是编译期契约,防止重写失效;多态仅适用于非static、非final、非private的实例方法,调用由运行时类型决定。

子类继承父类时,extends 关键字的使用限制

Java 中一个类只能单继承,即只能用 extends 指定一个直接父类。试图写成 class A extends B, C 会直接编译失败,报错:error: class A inherits from multiple classes(实际错误信息为 error: '{' expected 或更明确的 multiple inheritance not allowed)。

如果需要复用多个类型的行为,应改用 implements 实现接口。接口可多实现,例如:class Dog implements Runnable, Comparable 是合法的。

@Override 注解不是可选的“装饰”,而是编译期契约

重写父类方法时加不加 @Override 看似没区别,但漏写可能导致严重隐患:比如父类方法签名后期修改(如参数从 int 改为 long),子类未同步更新,又没加 @Override,编译器不会报错,结果变成定义了一个新方法,而非重写——多态调用时依旧执行父类逻辑,行为悄然偏离预期。

此外,@Override 还能防止拼写错误,例如把 toString() 错写成 toStirng(),不加注解时编译通过但毫无作用;加上后立即报 method does not override or implement a method from a supertype

多态调用的实际分派机制:编译时类型 vs 运行时类型

变量声明类型(编译时类型)决定**能调用哪些方法**,而实际指向的对象类型(运行时类型)决定**执行哪个版本的方法**。这是理解多态行为的关键分水岭。

Animal a = new Dog();
a.eat(); // ✅ 编译通过(Animal 有 eat()),运行时调用 Dog.eat()
a.bark(); // ❌ 编译失败:Animal 类没有 bark() 方法,哪怕 a 实际是 Dog

常见误解

是认为“只要对象是子类,就能调用子类特有方法”——错。必须通过子类引用或向下转型才能访问:

多态与 static / final / private 方法的关系

这三类方法在 Java 中都不参与动态绑定,即不支持多态。它们的调用目标在编译期就完全确定。

例如:

class Animal {
    static void sleep() { System.out.println("Animal sleep"); }
    final void breathe() { System.out.println("Animal breathe"); }
    private void hunt() { System.out.println("Animal hunt"); }
}
class Dog extends Animal {
    static void sleep() { System.out.println("Dog sleep"); }
    final void breathe() { System.out.println("Dog breathe"); } // 编译错误!final 方法不能重写
    private void hunt() { System.out.println("Dog hunt"); } // ✅ 合法,但这是新方法,与父类 hunt() 无关
}

真正参与多态的,只有非 static、非 final、非 private 的实例方法——而且前提是它们在继承链中被正确定义和重写。