当前位置: 首页 > news >正文

Java中的方法重写(Override)与方法重载(Overload)详解

一、基本概念对比

特性方法重写(Override)方法重载(Overload)
定义子类重新定义父类中已有的方法同一个类中多个同名方法,参数不同
作用范围继承关系中(父子类之间)同一个类内
方法签名必须相同(方法名+参数列表)必须不同(至少参数类型、个数或顺序不同)
返回类型相同或是父类方法返回类型的子类型(协变返回)可以不同
访问权限不能比父类方法更严格可以不同
异常抛出不能抛出比父类方法更多/更宽泛的检查型异常可以不同
静态性不能重写静态方法(隐藏不算重写)可以重载静态方法

二、方法重写(Override)

1. 重写规则

  • 必须继承关系(子类重写父类方法)
  • 方法名、参数列表必须完全相同
  • 返回类型相同或是其子类(Java 5+支持协变返回)
  • 访问修饰符不能比父类更严格(public > protected > default > private)
  • 不能抛出比父类方法更多的检查异常(非检查异常不受限)

2. 代码示例

class Animal {protected void makeSound() {System.out.println("Animal makes sound");}public Animal getInstance() {return new Animal();}
}class Dog extends Animal {// 正确重写 - 访问权限更宽松@Overridepublic void makeSound() {System.out.println("Dog barks");}// 协变返回类型 - 返回Dog而非Animal@Overridepublic Dog getInstance() {return new Dog();}
}

3. @Override注解

  • 非强制但强烈建议使用
  • 帮助编译器检查是否满足重写条件
  • 提高代码可读性
class Cat extends Animal {@Override  // 如果拼写错误会报编译错误public void makeSound() {System.out.println("Cat meows");}
}

4. 不能重写的情况

  • private方法:对子类不可见
  • final方法:禁止重写
  • static方法:属于类而非实例(可以"隐藏"但不是重写)

三、方法重载(Overload)

1. 重载规则

  • 必须在同一个类中
  • 方法名必须相同
  • 参数列表必须不同(类型、个数或顺序)
  • 返回类型可以不同(仅返回类型不同不算重载)
  • 访问修饰符可以不同
  • 可以抛出不同的异常

2. 代码示例

class Calculator {// 整数加法public int add(int a, int b) {return a + b;}// 重载1 - 参数类型不同public double add(double a, double b) {return a + b;}// 重载2 - 参数个数不同public int add(int a, int b, int c) {return a + b + c;}// 重载3 - 参数顺序不同public String add(String s, int n) {return s + n;}public String add(int n, String s) {return n + s;}
}

3. 自动类型转换与重载

class Printer {void print(int i) {System.out.println("int: " + i);}void print(double d) {System.out.println("double: " + d);}void print(String s) {System.out.println("String: " + s);}
}public class Main {public static void main(String[] args) {Printer p = new Printer();p.print(10);     // 调用print(int)p.print(10.0);   // 调用print(double)p.print("10");   // 调用print(String)p.print(10L);    // 自动转换,调用print(double)}
}

四、特殊场景分析

1. 父子类中的重载

class Parent {void process(int i) {System.out.println("Parent int: " + i);}
}class Child extends Parent {// 这是重载而非重写void process(double d) {System.out.println("Child double: " + d);}
}public class Test {public static void main(String[] args) {Child c = new Child();c.process(5);    // 调用Parent.process(int)c.process(5.0);  // 调用Child.process(double)}
}

2. 可变参数与重载

class VarArgsDemo {void process(int... nums) {System.out.println("Processing numbers");}void process(String... strs) {System.out.println("Processing strings");}// 会与上面两个方法冲突// void process(int n, String... strs) { ... }
}

3. 泛型方法重载

class GenericOverload {// 编译错误 - 类型擦除后签名相同// void process(List<String> list) { ... }// void process(List<Integer> list) { ... }// 合法重载void process(String s) { ... }void process(Integer i) { ... }
}

五、面试常见问题

1. 重写与重载的区别是什么?

  • 重写:父子类间,相同签名,实现不同
  • 重载:同类中,不同签名,功能相似

2. 构造方法能重写吗?

  • 不能,构造方法不能被继承
  • 但可以重载(一个类中多个构造方法)

3. main方法能重写或重载吗?

  • 不能重写(static方法)
  • 可以重载(但只有public static void main(String[])是入口)

4. 以下代码输出什么?

class A {void m1(Object o) { System.out.println("A"); }
}class B extends A {void m1(String s) { System.out.println("B"); }
}public class Test {public static void main(String[] args) {A a = new B();a.m1("hello");  // 输出"A"(因为m1(String)没有重写m1(Object))}
}

六、最佳实践

  1. 重写时总是使用@Override

    • 防止意外创建重载而非重写
    • 提高代码可读性
  2. 重载方法应保持功能一致

    • 不同参数形式实现相同功能
    • 避免让使用者困惑
  3. 谨慎使用可变参数重载

    • 容易导致调用歧义
    • 编译器可能无法确定最佳匹配
  4. 避免过于复杂的重载设计

    • 参数类型差异应明显
    • 考虑使用不同方法名提高可读性
  5. 注意自动装箱与重载

void process(Integer i) { ... }
void process(long l) { ... }process(5);  // 调用process(long),因为不需要自动装箱

通过深入理解方法重写和重载的区别与应用场景,可以设计出更加清晰、灵活的类结构,这是Java面向对象编程的重要基础。

相关文章:

  • 位运算练习:起床困难综合征(贪心,位运算)(算法竞赛进阶指南学习笔记)
  • 关于ubuntu密码正确但是无法登录的情况
  • 互联网大厂Java面试:从基础到进阶的技术点探讨
  • 短信验证码安全实战:三网API+多语言适配开发指南
  • C语言学习记录(17)编译和链接
  • vue3 + element-plus中el-drawer抽屉滚动条回到顶部
  • Scenario Dreamer:用于生成驾驶模拟环境的矢量化潜扩散模型
  • 【Linux禁用历史命令】
  • 从零开始配置 Zabbix 数据库监控:MySQL 实战指南
  • SSH 互信被破坏能导致 RAC 异常关闭吗
  • 脚本备份数据
  • 热敏电阻的应用说明
  • Centos虚拟机远程连接缓慢
  • 数据结构与算法-顺序表应用
  • 网络原理 - 4(TCP - 1)
  • AI深度伪造视频用于诈骗的法律定性与风险防范
  • Mysql的redolog
  • React:<></>的存在是为了什么
  • VMwaer虚拟机复制粘贴、ROS系统安装
  • 嵌入式软件测试的革新:如何用深度集成工具破解效率与安全的双重困局?
  • 国家卫健委:坚决反对美国白宫网站翻炒新冠病毒“实验室泄漏”
  • 特朗普激发加拿大爱国热情之下:大选提前投票人数创纪录,魁北克分离情绪被冲淡
  • A股三大股指涨跌互现:人形机器人产业链爆发,两市成交超1.2万亿元
  • 视频丨习近平同阿塞拜疆总统会谈:两国建立全面战略伙伴关系
  • 世界读书日丨人均一年超10本!你达到上海平均阅读水平了吗
  • 国产手术机器人+5G技术,上海医生同一天远程为五地患者开刀