引言
在上一节中我们学习了面向对象中的继承,然后在那一节中我们提到了一个知识点叫做:重写。
通过上节的代码样例我们也观察到了,重写是发生在子类和父类的这种继承关系中。
继承的特点就是提取所有子类共有的属性和方法,但是不同的子类可能对于同一方法有不同的业务处理逻辑。所以重写就是解决这一类问题的。
跟重写知识点名称比较相似的一个知识点叫做:重载,这两个知识点名称相似,所以我们把他们放在一个章节去详细讲解,帮助大家更好的掌握和区分。
正文
方法重写Override
定义
方法重写是子类对父类中的方法进行重新实现的过程。当子类中存在一个与父类同名、参数列表相同且返回类型兼容(或相同)的方法时,子类的方法会覆盖(或称为重写)父类中的方法。
规则
- 方法名和参数列表必须相同:子类的重写方法必须与父类中被重写的方法具有相同的函数名和参数列表,包括参数的顺序。
- 返回类型兼容:子类的重写方法的返回值类型必须等于或小于父类被重写方法的返回值类型,即子类的返回类型可以是父类返回类型的子类或者与父类返回类型一致。
- 异常类型兼容:子类重写方法所抛出的异常必须与父类中的被重写方法的异常一致,或者是父类抛出异常的子类,不能比父类的异常范围更宽泛。对于异常的概念我们放在后面章节中详细解释。
- 访问权限不能更低:子类重写方法的访问权限不能低于父类方法的访问权限。如果父类方法的访问权限是protected,那么子类方法的访问权限也必须是protected或更宽松的访问权限。
- private方法不能被重写:如果父类的方法被声明为private,那么子类不能对其进行重写。即使子类定义了同名的方法,也只是相当于定义了一个子类的新方法,与父类方法无关。
方法重载(Overload)
方法重载其实我们也接触过一种了,我们在学习类和对象的时候也了解了构造函数的概念,构造函数是一种特殊的函数,我们当时在类中声明了有参的构造函数和无参的构造函数,其实那也是一种方法重载的实现。
定义
方法重载是指在一个类中定义了多个同名的方法,但它们具有不同的参数列表。不同的参数列表可以是参数个数、参数类型或参数顺序上。虽然方法名相同,但是在方法的调用的时候根据参数去决定调用哪个函数。
规则
- 方法名必须相同:重载的方法必须具有相同的名称。
- 参数列表必须不同:重载方法的参数列表必须不同,这包括参数个数、参数类型或参数顺序的不同。
- 与返回类型无关:重载方法的返回类型可以相同也可以不同,方法的重载不是通过返回类型来区分的。
- 与访问权限和异常类型无关:重载方法的访问权限和抛出的异常类型与重载无关。
样例
class TestOverload {
//两个参数的add方法
public int add(int a, int b) {
return a + b;
}
//三个参数的add方法
public int add(int a, int b, int c) {
return a + b + c;
}
//两个String类型参数的add方法
public String add(String a, String b) {
return a + b;
}
public static void main(String[] args) {
TestOverload o = new TestOverload();
//下面根据参数传递去调用不通的方法。
int result1 = o.add(10, 20); // 调用两个参数的add方法
System.out.println(result1); // 输出 30
int result2 = o.add(10, 20, 30); // 调用三个参数的add方法
System.out.println(result2); // 输出 60
String result3 = o.add("10", "20"); // 调用字符串拼接的add方法
System.out.println(result3); // 输出 1020
}
}
总结
我们总结一下重写和重载的区别,很多的面试题中会提到这类的问题
1、重写是子类对父类方法的重新实现,而重载是在同一个类中定义多个同名但参数不同的方法。
2、重写发生在子类与父类之间,而重载发生在同一个类中