重写与重载的本质区别在于:1.发生位置不同——重载在同一个类内,重写在子类与父类之间;2.方法签名要求不同——重载要求参数列表不同,重写要求方法名和参数列表完全相同(返回值可协变);3.绑定时机不同——重载为编译期静态绑定,重写为运行期动态绑定。

区分重写(Override)和重载(Overload),关键看三点:发生位置、方法签名是否变化、以及绑定时机。本质差异不在表面写法,而在编译器或JVM如何识别和调用它。
看发生位置:类内 vs 类间
重载一定发生在同一个类内部,比如你给一个工具类写了多个同名的 parse() 方法,分别接收 String、int、byte[] —— 这是为适配不同输入而做的“横向扩展”。
重写则一定发生在子类与父类之间,比如 ArrayList 重写了 AbstractList 的 size(),目的是改变已有行为的“纵向定制”。
看方法签名:参数变不变
重载要求参数列表必须不同:类型不同、个数不同、顺序不同,三者满足其一即可;返回值、修饰符、异常声明全都不影响判断。
重写要求方法名 + 参数列表必须完全一致(包括类型、个数、顺序),连泛型擦除后的字节码签名都要匹配;返回值允许协变(如父类返回 Object,子类可返回 String),但不能更宽。
看绑定时机:编译期决定 vs 运行期决定
重载由编译器在编译时静态绑定:你写 calc(3.14),编译器直接查出该调用 calc(double),生成固定字节码,运行中不会换。
重写由 JVM 在运行时动态绑定:哪怕变量声明为父类类型(如 List list = new ArrayList();),实际执行时仍会根据 list 指向的对象真实类型,调用 ArrayList 中重写的 add()。
看限制条件:谁管得更严
重载几乎无约束:访问修饰符可任意(public/private 都行),异常可随便抛,甚至可以和父类重载方法共存。
重写有硬性规则(常记作“两同两小一大”):
• 方法名、参数列表必须相同
• 返回值类型 ≤ 父类(协变允许)、抛出异常 ≤ 父类(范围更窄)
• 访问权限 ≥ 父类(不能把 public 改成 protected)
• 父类方法不能是 private、final 或 static










