正确覆盖父类行为需满足四个硬性条件:方法签名完全一致、返回类型协变合法、访问权限不缩小、父类方法非final/static/private;@override仅作编译期校验,运行时以父类引用指向子类实例的多态调用为准。

正确覆盖父类行为,关键不是“加了 @Override 就算重写”,而是让子类方法在运行时真正替代父类逻辑,并符合 Java 的多态规则。核心在于签名匹配、权限合规、调用上下文正确——注解只是帮你看清是否真的覆盖成功。
必须满足的四个硬性条件
缺一不可,否则看似重写,实则只是新增方法或编译报错:
- 方法签名完全一致:方法名、参数个数、类型(注意 int 和 Integer 不等价)、顺序必须和父类一模一样
-
返回类型协变合法:可以相同,也可以是父类返回类型的子类(如父类返回
Number,子类可返回Integer);但不能反过来 -
访问权限不缩小:父类是
protected,子类不能是private或包级(默认);可升级为public -
父类方法本身可被重写:不能是
final、static或private——这三类方法根本不在继承链中暴露给子类
用 @Override 注解守住底线
它不参与运行,但能立刻拦截常见错误:
- 方法名拼错(比如
toString写成toSting),编译直接失败 - 参数少一个、类型用错(
List<string></string>vsArrayList<string></string>),编译器提示“找不到可重写的方法” - 父类方法被删掉或改名后,子类对应方法立刻暴露,避免“假覆盖”导致逻辑静默失效
不加也能运行,但等于裸奔——强烈建议每个重写方法都带上。
运行时验证是否真覆盖:看多态调用效果
覆盖是否生效,最终由对象实际类型决定,不是引用类型:
- ✅ 正确方式:
Animal a = new Dog(); a.makeSound();→ 执行Dog中的实现 - ❌ 错误场景:
Dog d = new Dog(); d.makeSound();看似调用子类,但若设计不当(如构造器中提前调用该方法),可能因字段未初始化导致异常——这不是覆盖失败,而是调用时机陷阱
真正检验覆盖成功的唯一标准:用父类引用指向子类实例,运行时执行的是子类方法体。
想增强而非替换?主动调用 super 是安全选择
如果不想丢掉父类逻辑,只需在子类方法中显式调用 super.xxx():
- 前置增强:
super.doWork(); System.out.println("记录日志"); - 后置增强:
System.out.println("发送通知"); super.doWork(); - 包裹增强:
log("start"); super.doWork(); log("end");
这种方式把控制权交还给开发者,比模板方法更直接,也更依赖约定。只要签名合规、调用得当,就能在保留原行为基础上叠加新逻辑。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











