方法重写是实现多态的关键机制,核心在于运行时根据实际对象类型决定调用哪个版本的方法;必须满足签名一致、返回类型兼容、访问修饰符不更严格等条件,且需使用@Override注解确保正确性。

方法重写是实现多态的关键机制,其核心不在于“子类写个同名方法”,而在于**运行时根据实际对象类型决定调用哪个版本的方法**。变量的声明类型只影响编译期检查,真正执行哪段代码,由 new 出来的对象实际类型决定。
重写必须满足“签名一致”
子类中重写父类方法,必须保证方法名、参数列表(类型、个数、顺序)完全相同,返回类型需兼容(Java 5 起支持协变返回类型,即子类可返回更具体的子类型)。访问修饰符不能比父类更严格(如父类是 protected,子类不能是 private),但可以更宽松(如改为 public)。
- 构造方法、static 方法、final 方法不能被重写
- private 方法对子类不可见,子类中同名方法属于新定义,不是重写
- 重写与重载(Overload)本质不同:重载看参数列表,发生在同一类;重写看实际对象类型,跨越父子类
变量类型影响编译,不影响运行时绑定
声明为父类类型的变量,可以引用子类对象(向上转型),这是多态的前提。此时:编译器只允许调用父类中声明过的方法;但运行时,JVM 查看该变量实际指向的对象类型,调用对应类中重写后的方法。
例如:Animal a = new Dog(); a.sound(); 编译通过(因为 Animal 有 sound()),运行时执行的是 Dog 类中的 sound() 实现。
- 若子类新增了父类没有的方法(如 Dog.bark()),用 Animal 类型变量无法直接调用,需强制转型
- 变量类型变化(如从 Animal 改为 Dog)只改变编译期可见性,不改变已有对象的行为逻辑
@Override 注解不是可选,而是必需习惯
显式添加 @Override 注解,让编译器帮你校验:是否真在重写父类方法。一旦父类方法签名变更或被删除,子类代码会立即报错,避免因拼写错误、参数差异等导致“假重写”——表面同名,实则成了独立方法,多态失效。
- 没有 @Override 却自以为重写了?运行时不会调用你的方法,而是调用父类原版,bug 难排查
- IDE 通常支持一键生成重写方法,并自动加注解,应养成依赖工具+注解双保险的习惯
重写中调用 super 是明确需求,不是默认行为
子类重写方法后,父类原逻辑不会自动执行。如需复用父类实现,必须显式写 super.methodName()。这体现“子类主导,按需委托”的设计原则。
- 常见于模板方法模式:父类定义流程骨架,子类重写钩子方法,内部主动调用 super 完成公共步骤
- 避免在重写方法里漏掉关键初始化或清理逻辑,只因忘了 super 调用
- super() 只能出现在构造方法第一行;super.method() 则无此限制,但语义上建议放在开头或结尾,保持逻辑清晰

















