Java Override/Overload
方法重写与重载的区别、重写规则与 @Override 注解。
重写(Override)
A subclass method with the same name and parameters overrides the parent's; calls dispatch to the child version. The @Override annotation lets the compiler verify the signature.
class Animal {
void move() {
System.out.println("animal moves");
}
}
class Dog extends Animal {
@Override
void move() {
System.out.println("dog runs");
}
}
public class OverrideDemo {
public static void main(String[] args) {
Animal a = new Dog();
a.move();
}
}dog runs方法的重写规则
An override must keep the same name and parameters, return the same type or a subtype (covariant return), not narrow visibility, not widen checked exceptions, and cannot target final, static or private methods.
| Rule | Allowed? |
|---|---|
| Same name and parameters | Required |
| Narrower access (public to private) | Forbidden |
| Wider checked exception | Forbidden |
| Covariant return type | Allowed |
| Override a final method | Forbidden |
重载(Overload)
Overloading means the same name with different parameters in one class; the compiler picks by argument types at compile time (static binding). Overriding is resolved at runtime from the object's real type (dynamic binding).
public class OverloadDemo {
static void show(int a) {
System.out.println("int: " + a);
}
static void show(String s) {
System.out.println("String: " + s);
}
static void show(int a, int b) {
System.out.println("two ints: " + a + "," + b);
}
public static void main(String[] args) {
show(1);
show("x");
show(1, 2);
}
}int: 1
String: x
two ints: 1,2重写与重载的区别
In one line: overriding rewrites a parent's behaviour in a subclass; overloading provides several parameter variants of one operation. The first is runtime polymorphism, the second compile-time selection.
| Aspect | Override | Overload |
|---|---|---|
| Where | Parent and child class | Same class |
| Signature | Must be identical | Must differ |
| Binding | Runtime | Compile time |
| Polymorphism | Yes | No |
重写(Override)
子类定义与父类同名同参数的方法即为重写,运行时调用子类版本。加上 @Override 注解可以让编译器帮你检查签名是否写错。
class Animal {
void move() {
System.out.println("animal moves");
}
}
class Dog extends Animal {
@Override
void move() {
System.out.println("dog runs");
}
}
public class OverrideDemo {
public static void main(String[] args) {
Animal a = new Dog();
a.move();
}
}dog runs方法的重写规则
重写必须满足:方法名与参数列表相同;返回类型相同或是其子类(协变返回);访问权限不能更小;不能抛更宽的受检异常;final、static、private 方法不能被重写。
| 规则 | 是否允许 |
|---|---|
| 同名同参数 | 必须 |
| 缩小访问权限 | 禁止 |
| 抛更宽的受检异常 | 禁止 |
| 协变返回类型 | 允许 |
| 重写 final 方法 | 禁止 |
重载(Overload)
重载是同一类中方法名相同、参数列表不同。编译器在编译期按实参类型决定调用哪个版本,这叫静态绑定;重写则是运行时按对象实际类型决定,叫动态绑定。
public class OverloadDemo {
static void show(int a) {
System.out.println("int: " + a);
}
static void show(String s) {
System.out.println("String: " + s);
}
static void show(int a, int b) {
System.out.println("two ints: " + a + "," + b);
}
public static void main(String[] args) {
show(1);
show("x");
show(1, 2);
}
}int: 1
String: x
two ints: 1,2重写与重载的区别
一句话区分:重写是「子类改写父类行为」,重载是「同一功能的不同参数版本」。前者是运行期多态,后者是编译期选择。
| 对比项 | 重写 | 重载 |
|---|---|---|
| 发生位置 | 父子类之间 | 同一个类中 |
| 方法签名 | 必须相同 | 必须不同 |
| 绑定时机 | 运行时 | 编译期 |
| 多态 | 是 | 否 |