重写的要求:
- 子类方法的形参列表和方法名必须和父类方法的形参列表和方法名一样
- 子类方法的返回类型必须是父类方法返回类型或为其子类型。例如父类方法返回类型为Object类,那么子类的返回类型可以是Object,也可以是String
- 子类方法的访问权限必须大于等于父类方法; (访问权限:public>default>protected>private)
- 子类方法抛出的异常类型必须是父类抛出异常类型或为其子类型。
重写和重载区别
重载(Overload) | 重写(Override) | |
---|---|---|
发生范围 | 本类 | 父子类 |
形参列表 | 形参类型/个数/顺序至少一个不同 | 父子类必须相同 |
返回类型 | 没有要求 | 子类方法的返回类型必须是父类方法返回类型或为其子类型 |
修饰符 | 无要求 | 子类方法的访问权限必须大于等于父类方法 |
扩展
在调用一个方法时,先从本类中查找是否有对应的方法(this.func(this)
)
如果没有再到父类中查找是否有对应的方法(super.func(this)
)
如果仍然没有就要将参数类型转成其父类类型之后再到本类中看是否有对应的方法(this.func(super)
)
如果仍然没有就再到父类中查找是否有对应的方法(super.func(super)
)
优先级:从高到低
this.func(this)
super.func(this)
this.func(super)
super.func(super)
this和super有点模糊的可以去看一下这篇 this和super关键字
案例
class One{
public void test(One obj) {
System.out.println("调用了One的方法,参数类型是One");
}
public void test(Three obj){
System.out.println("调用了One的方法,参数类型是Three");
}
public void test(){
System.out.println("1111111");
}
public void show(){
System.out.println("One show");
}
}
class Two extends One{
@Override
public void test(One obj){System.out.println("调用了Two的方法,参数类型是One");}
// @Override
// public void test(Three obj){
// System.out.println("调用了Two的方法,参数类型是Three");
// }
@Override
public void show(){
System.out.println("Two show");
}
}
class Three extends Two {}
class Four extends Three {}
public static void main(String[] args) {
One one = new One();
Two two = new Two();
Three three = new Three();
Four four = new Four();
one.test(one);
// one是One类创造的对象,参数类型是One类,先从One类中找是否有test(One obj)方法,有所以直接调用
// 结果:调用了One的方法,参数类型是One
one.test(two);
// one是One类创造的对象,参数类型是Two类,先从One类中找是否有test(Two obj)方法,
// 没有,所以到One类的父类Object中查看,Object也没有test(Two obj)方法
// 所以对参数进行转型,将Two类转成其父类One,再到One类中找是否有test(One obj)方法,有所以直接调用
// 结果:调用了One的方法,参数类型是One
two.test(three);
// two是Two类创造的对象,参数类型是Three类,先从Two类找是否有test(Three obj)方法
// 没有,所以到Two类的父类One中查看
// 找到One类中有test(Three obj)方法,直接调用
// 结果:调用了One的方法,参数类型是Three
two.test(four);
// two是Two类创造的对象,参数类型是Four类,先从Two类找是否有test(Four obj)方法
// 没有,所以到Two类的父类One中查看
// One类中没有test(Four obj)方法,所以到One类的父类Object中查看,Object也没有test(Four obj)方法
// 所以对参数进行转型,将Four类转成其父类Three
// 再到Two类中找是否有test(Three obj)方法,没有
// 再到Two类的父类One中看是否有test(Three obj)方法,有所以直接调用
// 结果:调用了One的方法,参数类型是Three
One one1 = new Two(); // 引用的是Two对象:父类One的引用指向子类的类型
//Two two1 = new One(); // 反过来不行,子类的引用不能指向父类
one1.test(one1);
// one1是Two类创造的对象,参数类型是Two类,先从Two类找是否有test(Two obj)方法
// 没有,所以找Two类的父类One,看是否有test(Two obj)方法
// 还是没有,所以到One类的父类Object中查看,Object也没有test(Two obj)方法
// 所以将参数类型Two类转为其父类One,再到本类(Two)查找是否有test(One obj)方法,有所以直接调用
// 结果:调用了Two的方法,参数类型是One
}