方法覆盖(override),指的是子类继承父类,在子类重写父类的方法,返回类型小于父类,方法名,参数列表要严格一致,这种行为我们称之为方法重写。
方法重载(overload),指的是相同类中方法名相同,参数列表不同,与权限修饰符和返回类型无关的这种现象称之为方法重载。
方法重写(overwrite),在java中权威认定不存在方法重写。
override作用于运行时多态,当子类继承了父类的方法,但是又不想原封不动的继承,这时候就需要用到override。
public class SuperClass{ public void callShow(){ System.out.println("显示号码"); } } public class SubClass extends SuperClass{ public void callShow(){ System.out.println("显示号码,显示头像"); } }
overload作用于编译时多态。
override的要求:
1、参数列表必须完全与被重写方法的相同;
2、返回类型与被重写方法的返回类型可以不相同,但是必须是父类返回值的派生类(java5 及更早版本返回类型要一样,java7 3、及更高版本可以不同);
3、访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类的一个方法被声明为public,那么在子类中重写该方5、法就不能声明为protected。
首先复习下权限修饰符:
当前类 | 同包 | 子类 | 不同包(无关类) | |
public | 可 | 可 | 可 | 可 |
protected | 可 | 可 | 可 | 不行 |
default | 可 | 可 | 不行 | 不行 |
privae | 可 | 不行 | 不行 | 不行 |
为什么覆盖方法要比被覆盖方法访问权限大?
public class SuperClass{ public void set(){} } public class SubClass extends SuperClass{ @override private void set(){//实际上这里是编译不通过的,假设编译通过 doSomeThing(); } public static void main(String[] args){ SuperClass sub = new SubClass();//向上转型 sub.set();//问题出在这里 } }
sub在调用set方法的时候,动态绑定实际调用的是子类的set方法。但是子类的set为private,Sub是访问不了的。这样就会存在问题,所以这种override在编译时过不了的。
拓展:什么是动态绑定。了解方法调用的全过程就理解了。
4、父类的成员方法只能被它的子类重写。
5、声明为final的方法不能被重写。
6、声明为static的方法不能被重写,但是能够被再次声明。
7、子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为private和final的方法。
8、子类和父类不在同一个包中,那么子类只能够重写父类的声明为public和protected的非final方法。
9、重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以。
10、构造方法不能被重写。
11、如果不能继承一个方法,则不能重写这个方法
overload要求:
1.方法的方法名一致,参数类型,个数,顺序必须有一个不一样。
这里必须要引入新的概念。确认一个方法的唯一性有三个要素:方法所属者,方法名,形参列表。(由于对于方法调用者来说返回值仅仅只是一个运行结果,调用者更关注的是形参所以返回值类型不在签名特征中,方法体难以判断也不再其中),对于不同类中的方法找到他只需要类权限定名加方法名基本可以确认,但是对于方法重载来说方法签名就显得有意义的多:方法签名由:形参列表和返回类型决定:我们可以用dos命令来查看一个方法的方法签名:javap -s 类权限定名。示例如下:
2.存在于相同类,子父类中。
3.返回值类型不一样不构成重载。(这样在编译时是不通过的)
原文:https://www.cnblogs.com/silencelp/p/14715127.html