方法重写概述

方法重写(Method Overriding)是面向对象编程的核心特性之一

学习目标

理解方法重写的概念、作用及与重载的区别,掌握正确的重写语法

什么是方法重写?

方法重写是指子类重新定义父类中已有的方法,提供与父类不同的实现。

特点:

  • 发生在子类与父类之间
  • 方法名、参数列表完全相同
  • 返回类型相同或是其子类型
  • 访问权限不能更严格

重写 vs 重载

区别点 方法重写 方法重载
发生位置 子类与父类之间 同一个类中
参数列表 必须相同 必须不同
返回类型 相同或子类型 可以不同
访问修饰符 不能更严格 可以不同

方法重写规则详解

掌握方法重写的具体规则和限制条件

1

方法签名必须相同

方法名、参数列表(类型、顺序、数量)必须完全一致

public class Animal { public void makeSound() { System.out.println("动物叫声"); } } public class Dog extends Animal { @Override public void makeSound() { // 正确:签名完全相同 System.out.println("汪汪!"); } }
2

访问权限规则

子类方法的访问权限不能比父类方法更严格

public class Parent { protected void display() { } // protected } public class Child extends Parent { @Override public void display() { } // 正确:public > protected }
3

返回类型协变

返回类型可以是父类方法返回类型的子类型

public class Animal { public Animal getInstance() { return new Animal(); } } public class Dog extends Animal { @Override public Dog getInstance() { // 正确:Dog是Animal的子类 return new Dog(); } }
4

异常声明规则

重写方法抛出的异常范围不能大于父类方法

import java.io.*; public class Parent { public void read() throws IOException { } } public class Child extends Parent { @Override public void read() throws FileNotFoundException { } // 正确:范围更小 }

@Override注解详解

了解@Override注解的作用和使用场景

注解作用

  • 告诉编译器这是一个重写方法
  • 编译器会检查是否符合重写规则
  • 提高代码可读性和安全性
  • 帮助发现拼写错误或签名不匹配

使用示例

public class Employee { public String getDetails() { return "员工信息"; } } public class Manager extends Employee { @Override // 编译器会验证这个方法是否正确重写了父类方法 public String getDetails() { return "经理信息:奖金+" + bonus; } }

不使用@Override的风险

如果不使用@Override注解,当方法签名有误时,编译器会认为这是一个新方法,而不是重写,导致运行时行为不符合预期。

实战案例

通过实际案例理解方法重写的应用

1

形状类层次结构

创建一个几何图形类层次结构,实现面积计算的方法重写

// 父类:Shape.java public abstract class Shape { protected String color; public Shape(String color) { this.color = color; } public abstract double calculateArea(); public String getInfo() { return "这是一个" + color + "的形状"; } } // 子类:Circle.java public class Circle extends Shape { private double radius; public Circle(String color, double radius) { super(color); this.radius = radius; } @Override public double calculateArea() { return Math.PI * radius * radius; } @Override public String getInfo() { return super.getInfo() + ",半径:" + radius; } } // 子类:Rectangle.java public class Rectangle extends Shape { private double width, height; public Rectangle(String color, double width, double height) { super(color); this.width = width; this.height = height; } @Override public double calculateArea() { return width * height; } }
2

测试类

public class ShapeTest { public static void main(String[] args) { Shape circle = new Circle("红色", 5.0); Shape rectangle = new Rectangle("蓝色", 4.0, 6.0); System.out.println(circle.getInfo() + ",面积:" + circle.calculateArea()); System.out.println(rectangle.getInfo() + ",面积:" + rectangle.calculateArea()); } }

运行结果

程序输出:

这是一个红色的形状,半径:5.0,面积:78.53981633974483 这是一个蓝色的形状,面积:24.0

常见错误与解决方案

避免方法重写中的常见陷阱

错误1:方法签名不匹配

public class Parent { public void print(String msg) { } } public class Child extends Parent { // 错误:参数类型不匹配,这不是重写 public void print(Object msg) { } }

解决方法:确保方法名和参数列表完全相同

错误2:访问权限更严格

public class Parent { public void show() { } } public class Child extends Parent { // 错误:protected比public更严格 protected void show() { } }

解决方法:子类方法的访问权限必须大于或等于父类方法

错误3:final方法被重写

public class Parent { public final void display() { } } public class Child extends Parent { // 错误:final方法不能被重写 public void display() { } }

解决方法:final方法不能被重写,考虑使用其他方法名

错误4:静态方法重写

public class Parent { public static void staticMethod() { } } public class Child extends Parent { // 这不是重写,而是隐藏(hiding) public static void staticMethod() { } }

注意:静态方法不能被重写,这称为方法隐藏(method hiding)

最佳实践总结

方法重写的黄金法则和实用建议

必须遵循的规则

  • 始终使用@Override注解
  • 保持方法签名完全一致
  • 返回类型相同或协变
  • 访问权限不能更严格
  • 异常范围不能更大

设计建议

  • 重写时调用super.method()保留父类行为
  • 在Javadoc中说明重写行为
  • 考虑使用模板方法模式
  • 保持方法语义的一致性

实战练习

完成以下练习巩固方法重写知识:

  • 创建一个BankAccount类,包含deposit()和withdraw()方法
  • 创建SavingsAccount子类重写withdraw()方法,添加透支保护
  • 创建CreditAccount子类重写withdraw()方法,实现信用额度检查
  • 使用多态测试不同账户类型的行为
查看练习答案

知识清单

  • 理解方法重写的概念和作用
  • 掌握方法重写的5大规则
  • 熟练使用@Override注解
  • 识别并避免常见重写错误
  • 能够在实际项目中正确使用方法重写