方法重载与重写的核心区别对比


1. 基本概念
特性 方法重载 (Overloading) 方法重写 (Overriding)
定义 同一类中,方法名相同但参数列表不同 子类重新定义父类中方法名、参数、返回类型完全相同的非私有方法
核心目的 提供同一功能的多种参数调用方式 实现多态,允许子类定制父类行为
作用范围 同一类或父子类(继承链中) 仅限子类与父类之间

2. 核心规则对比

方法重载 (Overloading)
// 示例:不同参数类型的加法重载
class Calculator {
    // 整数相加
    int add(int a, int b) {
        return a + b;
    }
    
    // 浮点数相加(参数类型不同)
    double add(double a, double b) {
        return a + b;
    }
    
    // 三数相加(参数数量不同)
    int add(int a, int b, int c) {
        return a + b + c;
    }
}

关键规则

  • 方法名必须相同
  • 参数列表必须不同(类型、数量、顺序)
  • 返回类型、访问修饰符、抛出异常可不同
  • 可在同一类或继承链中定义

方法重写 (Overriding)
// 父类定义
class Animal {
    public void makeSound() {
        System.out.println("Animal makes a sound");
    }
}

// 子类重写
class Dog extends Animal {
    @Override
    public void makeSound() {  // 方法名、参数、返回类型完全一致
        System.out.println("Dog barks: Woof!");
    }
}

关键规则

  • 方法名、参数列表、返回类型必须相同
  • 访问权限不能比父类更严格(如父类 protected,子类不能为 private
  • 不能抛出比父类更宽泛的异常(如父类抛 IOException,子类不能抛 Exception
  • 仅适用于继承关系的子类中

3. 核心差异速查表

对比维度 方法重载 方法重写
参数列表 必须不同 必须相同
返回类型 可不同 必须相同(或协变类型)
访问权限 可不同 不能更严格(如父类 public,子类不能 protected
异常处理 可抛出任何异常 不能抛出更宽泛的异常
调用机制 编译时根据参数静态绑定 运行时根据对象类型动态绑定(多态)

4. 典型场景示例

场景 1:重载的实际应用

需求:一个工具类支持多种数据打印格式

class Printer {
    void print(String text) {
        System.out.println("String: " + text);
    }
    
    void print(int number) {
        System.out.println("Integer: " + number);
    }
    
    void print(double number) {
        System.out.println("Double: " + number);
    }
}

// 调用示例
Printer printer = new Printer();
printer.print("Hello");  // 输出 String: Hello
printer.print(100);      // 输出 Integer: 100
printer.print(3.14);     // 输出 Double: 3.14

场景 2:重写的实际应用

需求:不同图形计算面积的实现

// 父类定义抽象方法
class Shape {
    public double calculateArea() {
        return 0.0;
    }
}

// 子类重写
class Circle extends Shape {
    private double radius;
    
    public Circle(double radius) {
        this.radius = radius;
    }
    
    @Override
    public double calculateArea() {
        return Math.PI * radius * radius;
    }
}

class Rectangle extends Shape {
    private double width;
    private double height;
    
    public Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }
    
    @Override
    public double calculateArea() {
        return width * height;
    }
}

// 调用示例
Shape shape1 = new Circle(5.0);
Shape shape2 = new Rectangle(4.0, 6.0);
System.out.println(shape1.calculateArea()); // 输出 78.5398...
System.out.println(shape2.calculateArea()); // 输出 24.0

5. 常见误区与注意事项

误区 1:仅改变返回类型不算重载
class Example {
    int process(int x) { return x; }
    double process(int x) { return x * 1.0; } // 编译错误:重复定义
}
误区 2:静态方法不能被重写
class Parent {
    static void show() { System.out.println("Parent"); }
}

class Child extends Parent {
    static void show() { System.out.println("Child"); } // 方法隐藏(非重写)
}

// 调用示例
Parent obj = new Child();
obj.show(); // 输出 Parent(静态方法无多态)
误区 3:子类重写方法缩小访问权限
class Parent {
    public void demo() {}
}

class Child extends Parent {
    @Override
    void demo() {} // 编译错误:不能从 public 改为默认权限
}

6. 总结与选择策略

场景 选择技术
需要同一功能支持不同参数类型/数量 方法重载 (Overloading)
需要子类提供父类方法的不同实现 方法重写 (Overriding)

核心记忆点

  • 重载:同类中方法名相同,参数不同
  • 重写:子类中方法名、参数、返回类型与父类相同,实现不同逻辑

你可能感兴趣的:(Java基础,java)