💡 一、基础定义


方法重写(也叫方法覆盖)是面向对象编程中实现多态的核心机制,指在继承关系中,子类对父类继承来的可访问非私有方法,进行逻辑上的重新实现,让子类拥有自己的专属行为。
 


✅ 二、重写的前提条件


必须同时满足以下3点:
 
1. 存在继承/实现关系:子类继承父类(类继承),或者类实现接口(接口实现)
2. 父类方法可被继承:非 private 、非 final 、非 static ( static 方法只能隐藏,不能重写)
3. 子类方法与父类方法的方法签名完全一致:方法名 + 参数列表(个数、类型、顺序)完全相同
 


⚖️ 三、核心语法规则(必须严格遵守)


🎯 1. 返回值类型规则
 
1. 基本数据类型 /  void :必须完全相同
2. 引用数据类型:可以是父类返回值类型的子类(协变返回类型,Java 5+支持)
示例:父类返回 Animal ,子类可以返回 Dog ( Dog 是 Animal 的子类)
 
🔐 2. 访问权限规则
子类方法的访问权限不能严于(缩小)父类,只能宽松或相等
权限等级从大到小: public  >  protected  > 包访问权限(默认,无修饰符)>  private 
注意事项:
 
1. 父类 public  → 子类只能 public 
2. 父类 protected  → 子类可以 protected / public 
3. 父类包访问 → 子类可以包访问/ protected / public 
4. 父类 private  → 子类无法继承,不存在重写(子类写同名方法是独立新方法)
 
⚠️ 3. 异常规则
子类方法抛出的异常不能宽于父类,只能是父类异常的子类,或者不抛异常
 
1. 父类无异常:子类只能不抛异常,或仅抛运行时异常( RuntimeException 及其子类),不能抛编译时异常
2. 父类抛编译时异常:子类只能抛该异常的子类,或不抛
3. 父类抛运行时异常:子类无限制(可抛同类型、子类、不抛)
 
🚫 4. 特殊方法的重写限制
 
1.  static 静态方法:不能重写,只能「方法隐藏」(子类写同名 static 方法,调用时看引用声明类型,不看实际对象)
2.  final 方法:不能重写(父类用 final 修饰是为了禁止方法被修改,保证安全性)
3.  private 方法:不能重写(仅父类内部可见,子类无法继承)
4. 构造方法:不能重写(构造方法名与类名一致,子类构造方法名不同,只能通过 super() 调用父类构造)
 


🌟 四、特殊场景补充


🖥️ 1. 接口方法的重写(实现)
 
1. 类实现接口时,必须重写所有抽象方法(否则子类必须是抽象类)
2. 接口的 default 默认方法(Java 8+):类可以选择重写,或直接使用默认实现;若多接口存在同名默认方法,类必须重写解决冲突
3. 接口的 static 方法:不能被实现类重写,只能通过接口名调用
4. 接口的私有方法(Java 9+):仅接口内部使用,无法被重写
 
🎨 2. 抽象方法的重写
 
1. 子类继承抽象类时,必须重写所有抽象方法,否则子类也必须声明为抽象类
 
📢 3.  super 关键字调用父类重写方法
子类重写父类方法后,若仍需执行父类的原始逻辑,可通过 super.方法名() 调用父类方法:
 
java   

class Animal {
    void makeSound() {
        System.out.println("动物叫");
    }
}
class Dog extends Animal {
    @Override
    void makeSound() {
        super.makeSound(); // 先执行父类逻辑
        System.out.println("狗汪汪叫"); // 再执行子类逻辑
    }
}


 
 
🎭 4. 重写的本质:运行时多态(动态绑定)
Java在运行时根据对象的实际类型(而非引用声明类型)调用对应方法,这是多态的核心:
 
java   

Animal a = new Dog(); // 父类引用指向子类对象
a.makeSound(); // 运行时调用Dog类的makeSound(),而非Animal类


 
 
对比: static 方法是编译时绑定,看引用声明类型,属于方法隐藏,不是重写
 


🏷️ 五、 @Override 注解的作用


强烈建议在重写方法上添加 @Override 注解:
 
1. 编译时检查:编译器会验证该方法是否真的重写了父类方法,若方法名/参数/返回值写错,直接编译报错,避免逻辑错误
2. 代码可读性:让开发者一眼识别这是重写的方法
3. 注意:即使不写该注解,符合重写规则的方法依然会生效,但不推荐省略
 


📊 六、易混概念对比表
 


特性 方法重写(Override) 方法重载(Overload) 方法隐藏(Hide) 
存在关系 子类-父类(继承/实现) 同一个类内部 子类-父类(仅 static 方法) 
方法名 必须相同 必须相同 必须相同 
参数列表 完全一致 必须不同(个数/类型/顺序) 完全一致 
返回值类型 基本类型/ void 必须相同;引用类型可协变 无限制 必须相同(引用类型可协变) 
访问权限 不能缩小父类权限 无限制 不能缩小父类权限 
绑定时机 运行时(动态绑定) 编译时(静态绑定) 编译时(静态绑定) 
调用依据 对象的实际类型 编译时的参数类型 引用的声明类型 
适用方法类型 非 static /非 final /非 private  所有方法(含 static 、构造) 仅 static 方法 
 


❌ 七、常见错误与误区
 

1. 子类缩小父类访问权限(如父类 public ,子类 private )→ 编译报错
2. 子类抛出更宽泛的异常(如父类抛 IOException ,子类抛 Exception )→ 编译报错
3. 把 static 方法当成非 static 方法重写 → 编译报错(方法签名冲突)
4. 重写父类 private 方法 → 不是重写,子类是独立新方法
5. 省略 @Override 注解,写错方法名/参数 → 变成重载,运行时逻辑错误
6. 认为构造方法可以重写 → 构造方法只能调用,不能重写
 


💻 八、实际应用场景
 


1. 模板方法模式:父类定义算法骨架,子类重写具体步骤
2. 集合框架实现: ArrayList 重写 AbstractList 的 add() 、 get() 等方法
3. 接口实现:自定义类实现 Runnable 接口,重写 run() 方法
4. 重写 Object 类方法:所有类都继承 Object ,常重写:
1.  equals() / hashCode() :保证相等对象哈希值相等
2.  toString() :自定义对象打印信息
3.  clone() :实现对象的深克隆
5. 多态业务场景:如父类 Shape (图形),子类 Circle / Rectangle 重写 area() 方法,实现不同图形的面积计算
 


✅ 九、核心知识点总结


方法重写是Java多态的核心,必须满足方法签名一致、返回值协变/相同、权限不缩小、异常不宽泛四大核心规则;仅适用于继承/实现关系中的非 static 、非 final 、非 private 方法;通过 @Override 注解可避免错误,是面向对象编程的基础知识点。
 
 
 

更多推荐