面试题解七 - java 重载和重写的区别
重载和重写的区别
java中方法的重载和重写都是实现多态性的一种方式,区别在于前者实现多态性是在编译的时候,后者实现多态性是在运行的时候。
----重写(Override)----
重写的前提是继承,是子类对父类的方法的实现过程进行重新编写,方法重写参数类型、个数、顺序必须完全一致。重写的主要作用在于可以根据子类的需要,来特定属于子类的特定行为,这也是java多态性的一种实现方式。
例子:我们先创建一个动物类,该类中有一个move方法
public class Animal {
public void move(){
System.out.println("动物在跑动");
}
}
我们再创建一个猫类,猫类继承动物类并且重写move方法
public class Cat extends Animal {
@Override
public void move() {
System.out.println("猫可以跑也可以走");
}
}
这个子类中的move方法的方法名与父类一样,而且参数都为空,所以作为子类的猫类的move方法是对父类move方法的重写
public class TestCat {
public static void main(String[] args) {
Animal a = new Animal();
Animal b = new Cat();
a.move();//执行父类animal中的move方法
b.move();//执行子类cat中的move方法
}
}
输出结果:
说明在运行的时候,jvm选择了运行了特定对象b中重写的move方法
方法重写规则总结
- 父类的成员方法只能被它的子类重写,继承是重写的前提
- 参数列表与被重写方法的参数列表必须完全相同
- 访问权限不能比父类中被重写的方法的访问权限更低。若父类的方法权限修饰符
为public,那么子类方法重写的修饰符权限不能比public小(比如不能声明为
protected) - 声明为 final 的方法不能被重写
- 声明为 static 的方法不能被重写,但是能够被再次声明
- 父类的构造方法,子类无法对其进行重写
- 重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。但是,
重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性
异常,反之则可以 - 子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为
private 和 final 的方法 - 子类和父类不在同一个包中,那么子类只能够重写父类的声明为 public 和
protected 的非 final 方法 - 返回类型与被重写方法的返回类型可以不相同,但是必须是父类返回值的派生类 (java5 及更早版本返回类型要一样,java7 及更高版本可以不同)
super关键字
当子类重写了父类的方法后,想要用到重写前父类的方法,就得使用super关键字
例子:
public class Animal {
public void move(){
System.out.println("动物在跑动");
}
}
public class Cat extends Animal {
@Override
public void move() {
super.move();
System.out.println("猫可以跑也可以走");
}
public static void main(String[] args) {
Animal a = new Cat();
a.move();
}
}
运行之后可以看到父类中被重写之前的方法被调用了
重载(Overload)
重载是在同一个类中进行的,同类中方法名相同,但是参数不同的方法就是重载方法,返回值类型不一定要相同。每一个重载的方法都必须满足要有一个独一无二的参数列表,这也是jvm决定运行哪一个方法的判别关键点。
public class Overload {
//参数不同,返回值也不相同
public int test1(){
return 1;
}
public void test2(int a){
System.out.println(a);
}
//返回值类型相同,参数顺序不同
public void test3(int a,String b){
System.out.println(b + a);
}
public void test4(String a, int b){
System.out.println(a + b);
}
public static void main(String[] args) {
Overload overload = new Overload();
System.out.println(overload.test1());
overload.test2(2);
overload.test3(3,"c");
overload.test4("d",4);
}
}
运行结果:
重载规则
- 返回值类型并不是重载函数的区分标准,被重载的方法可以改变返回类型也可以不改变
- 被重载的方法必须改变参数列表(参数个数、类型、顺序至少有一项不一样)
- 被重载的方法可以改变访问修饰符
- 被重载的方法可以声明新的或更广的检查异常
- 方法重载只能发生在同一个类中
区别点 | 重载 | 重写 |
---|---|---|
返回类型 | 可以修改 | 一定不能修改 |
参数列表 | 必须修改 | 一定不能修改 |
异常 | 可以修改 | 可以减少或者删除,但是不能抛出新的或者更广的异常 |
访问权限 | 可以修改 | 无法改为更严格的限制,可以降低限制 |