方法的重写或方法的覆盖(overriding)

  • 子类根据需求从父类继承的方法进行重新编写
  • 重写时,可以用super.方法的方式来保留父类的方法
  • 构造方法不能被重写

方法重写规则

  1. 方法名相同,参数列表相同
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//父类
public class Father {
public void method1(){
System.out.println("父类的method1方法");
}
}
//子类
public class Son extends Father{
public void method1(){
System.out.println("子类的method1方法");
}

public static void main(String[] args) {
Son son = new Son();
son.method1();
}
}

输出:子类的method1方法

  1. 返回值类型相同或者是其子类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//父类
public class Father {
//方法返回值类型可以是自定义的数据类型
public Father method1(){
return new Father();
}
}
//子类
public class Son extends Father{
//子类方法返回值类型可以是父类方法返回值类型的子类,也是方法重写
public Son method1(){
System.out.println("子类重写后的method1方法");
return new Father();
}

public static void main(String[] args) {
Son son = new Son();
son.method1();
}
}

输出:子类重写后的method1方法

  1. 访问权限不能严于父类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//父类
public class Father {
//子类重写方法不可以比父类方法访问权限小,可以扩大方法的访问权限
//子类方法只要访问权限不严于父类,就构成了方法重写
void method1(){
System.out.println("父类的method1方法");
}
}
//子类
public class Son extends Father{

public Son method1(){
System.out.println("子类重写后的method1方法");
}

public static void main(String[] args) {
Son son = new Son();
son.method1();
}
}

输出:子类重写后的method1方法

  1. 父类的静态方法不能被子类覆盖为静态方法,父类的非静态方法不能被子类覆盖为静态方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//父类
public class Father {
public static void method1(){
System.out.println("父类的静态method1方法")
}
}
//子类
public class Son extends Father{
//父类的静态方法不能被重写为非静态方法
//反之,父类的非静态方法也不能被重写为静态方法
public void method1(){
System.out.println("子类重写后的非静态method1方法");
}

public static void main(String[] args) {
Son son = new Son();
son.method1();
}
}

输出:报错

  1. 子类可以定义与父类同名的静态方法,以便在子类中隐藏父类的静态方法(注:静态方法中无法使用super)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//父类
public class Father {
public static void method1(){
System.out.println("父类的静态method1方法");
}
}
//子类
public class Son extends Father{
//在子类中可以定义和父类一模一样的静态方法
public static void method1(){
//在静态方法中不能使用super
//super.method1();
Father.method1();
System.out.println("子类重写后的静态method1方法");
}

public static void main(String[] args) {
Son son = new Son();
son.method1();
}
}

输出:

父类的静态method1方法
子类重写后的静态method1方法

  1. 父类的私有方法不能被子类覆盖
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//父类
public class Father {
private void method1(){
System.out.println("父类的私有method1方法");
}
}
//子类
public class Son extends Father{
// 子类无法重写父类的private方法
public void method1(){
System.out.println("子类的私有method1方法");
}

public static void main(String[] args) {
Son son = new Son();
son.method1();
}
}

输出:子类的私有method1方法

  1. 不能抛出比父类方法跟多的异常

重载和重写的区别

比较项 位置 方法名 参数表 返回值 访问修饰符
方法重写 子类 相同 相同 相同或是其子类 不能比父类更严格
方法重载 同类 相同 不相同 无关 无关

方法重载:同一个类中同名不同参跟访问修饰符以及返回值类型无关的叫重载

方法重写:在父子类中同名同参,返回值可以和父类返回值相同,可以是子类,访问修饰符只要不严于父类就行。