前言
在实际项目中常会遇到许多功能相似的类,这时我们只有正确的理解了重载和重写的用法才能设计出清晰而简洁的类,可以说重写和重载在编写代码过程中的作用非同一般。本文也将着重介绍两者的区别以及应用场景。
区别
1.override 覆写(重写)
重写发生在子类继承父类时,覆写(重新实现)父类中的方法。
- 重写方法的参数列表必须完全与被重写的方法相同,否则不能称为重写而是重载。
- 重写方法的访问修饰符一定要大于被重写方法的访问修饰符(
public
>protected
>default
>private
)。 - 重写的方法的返回类型必须和被重写的方法的返回类型一致。
- 重写的方法所抛出的异常必须和被重写方法所抛出的异常一致,或是其子类异常。
- 被重写的方法不能为
private
,否则在其子类中只是新定义了一个方法,不构成重写。
下面看看覆写的例子
//父类
public class OverrideParent {
public void fly(){
System.out.println("Bird can fly");
}
}
//子类
public class OverrideChild extends OverrideParent{
@Override
public void fly() {
System.out.println("Bird can't fly, Plane can fly");
}
public static void main(String[] args) {
OverrideParent child = new OverrideChild();
child.fly();
}
}
输出结果:
Bird can't fly, Plane can fly
通过这个例子我们可以看到:
- OverrideParent 和 OverrideChild都有一个共同的方法fly。
- fly的返回值和参数形式都一样,只是方法体不一样。
- 子类的fly方法前有一个
@overwrite
的注解,jdk1.5出现的,仅用于类的继承,1.6可用于接口实现。这个注解有助于编译器检查,不加也可以的。
2.overload 重载
重载一般是用于一个类内实现若干重载的方法,方法名相同而参数形式不同。
- 在使用重载时只能通过相同的方法名,不同的参数形式实现。不同的参数形式可以是不同的参数类型、不同的参数个数、不同的参数顺序(参数类型必须不一样)。
- 不能通过访问权限、返回类型、抛出的异常进行重载。
- 方法的异常类型和数目不会对重载造成影响。
下面再来看看重载的例子
public class OverloadParent {
public String getMyInfo(String name){
return "My name is " + name;
} //1
public String getMyInfo(int age){
return "My age is " + age;
} //2
public String getMyInfo(String name, int age){
return "My name is " + name + "and age is " + age;
} //3
public void getMyInfo(String name){
System.out.println("My name is " + name);
} //4
}
注意观察:
- OverloadParent中有四个方法名相同的方法。
- 前三个方法方法名相同,参数形式不同,构成重载。
- 方法4和方法1仅仅返回值不同,不构成重载,并且编译器不通过。返回值是方法执行后的结果,不能通过不同的返回来来实现重载。
应用场景
重载:当方法功能相似,但需要传递不同的参数。
重写:子类有自己特有的行为,从父类继承而不能满足自身需要时。
ps:重载和覆写都是多态的表现。前者是编译器多态,后者是运行期多态。