一、定义
方法重写:子类继承父类后,在子类中声明的与父类同名同参的方法;
方法重载:在同一个类中,同名不同参的方法之间构成方法重载;
二、具体规则
方法重写:同一个类中,同方法名,参数不同,具体指:参数数量、参数类型、参数顺序;
方法重载:
- 子类重写的方法与父类被重写的方法名称相同、参数相同;
- 子类重写方法的权限修饰符不小于父类被重写方法的权限修饰符;
- 父类返回值类型为void时,子类重写的方法返回值必须是void;父类返回值类型为基础数据类型时,子类也必须是相同的基础数据类型;父类返回值是A类型时,子类返回值必须是A类或者A类的子类型;
- 子类抛出的异常为父类的同种异常,或者父类抛出异常的子异常;
三、从编译的角度看
重写:表现为多态性,对于多态,在方法调用那一刻,才能确定具体要调用的方法
重载:不构成多态;对于重载而言,在方法调用之前,编译器就确定了要调用的方法;
同一个类中允许存在同名不同参的方法,在编译器编译时,会对参数列表不同的方法名进行修饰,从而对于编译器来说,这些同名不同参的方法成为了不同的方法,这些方法的调用地址在编译期就绑定了;
四、代码验证
父类:Person
// 父类
public class Person {
// 声明属性
String name;
int age;
// 构造器:有参\无参
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// 方法
public void eat(){
System.out.println("吃饭");
}
public void walk(int distance){ // walk方法内调用show()和eat()
show(); // 未被子类Students重写
eat(); // 被子类Students重写
System.out.println("步行了" + distance + "公里");
}
private void show(){
System.out.println("我是一个人");
}
public Object info(){
return null;
}
public void sleep() {
System.out.println("人需要睡觉");
}
}
子类:Students
// 子类
public class Students extends Person{
String major;
public Students() {
}
public Students(String major) {
this.major = major;
}
public void study(){
System.out.println("学习的专业是" + major);
}
// 对父类中eat()方法进行了重写
public void eat(){
System.out.println("学生要多吃有营养的食物");
}
// 父类中与show同名的方法的权限修饰符为private,不构成重写
public void show(){
System.out.println("我是一名学生");
}
// 返回值类型String是Object的子类
public String info(){
return null;
}
// 不构成重写,只是同名方法
// @Override // @Override可以用于检验下面方法是否是重写父类方法,此时编译错误
public void sleep(int time){
}
}
测试类; TestPerson
public class TestPerson {
public static void main(String[] args) {
Students s = new Students("计算机科学与技术");
s.eat(); // 运行结果:学生要多吃有营养的食物
// 检验父类private方法是否可以被子类重写
s.walk(10);
/*
* 运行结果:
* 我是一个人 (表明show不是重写的方法)
* 学生要多吃有营养的食物 (表明eat是重写的方法)
* 步行了10公里
*/
System.out.println("-----------------");
s.study();
}
}