本文已收录《Java常见面试题》:https://gitee.com/mydb/interview在面向对象编程中,方法覆盖(override)是一种语言特性,它是多态性的具体体现,它允许类重定义了父类中已有的方法,子类中的方法名、参数类型和数量必须与父类一致,这就是方法重写。最简单的方法重写示例如下。定义一个父类Father和一个子类Son。父类中有method方法,子类中会重写method方法。具体实现代码如下。父类Father的实现代码如下:/***父类*/classFather{publicvoidmethod(Stringname){System.out.println("Father:"+name);}}在子类Method中重写父类方法,具体实现代码如下:/***Subclass*/classSonextendsFather{@Overridepublicvoidmethod(Stringname){//重新定义了打印的行为在子类中,不再是Father:XXX,而是Son:XXXSystem.out.println("Son:"+name);}}在程序中调用并执行method方法,具体实现代码如下:publicclassOverrideExample{publicstaticvoidmain(String[]args){Fatherfather=newSon();father.method("Java");}}上述程序的执行结果如下图所示:但是,在方法重写的过程中,还需要注意以下问题。注1:子类权限控制字符不可减少。Java中权限控制符的级别是:public>protected>none>private如果父类中的方法定义了protected控制符,具体实现代码如下:classFather{protectedvoidmethod(Stringname){System.out.println("父亲:"+姓名);那么此时如果子类重写了父类的方法,定义的权限控制符小于protected就会报错,如下图所示:那么问题来了,访问控制符是否可以在子类变大了?答案是肯定的,如下图:结论:子类重写父类的方法时,重写的方法权限控制符号不能减少,可以等于或大于父类权限控制符号.注2:子类的返回值类型只能归约。在说这个笔记之前,我们先来看一下前置知识。在Java语言中,Number类是Long的父类。继承关系如下图所示:接下来我们在父类中使用Number类型来表示方法的返回类型:classFather{publicNumbermethod(intnum1,intnum2){returnnum1+num2;}}在子类类型的实现中使用Number类型的子类Long,是可以正常重写父类的方法的,如下图所示:当然,如果符合也是可以的父类的返回类型,如下图所示:但是,如果尝试在子类中修改返回类型为太大,则会报错,如下图(ObjectisNumber类型的父类):注3:抛出异常的类型只能归约。如果子类抛出的异常类型变大,则为子类方法抛出的异常类型如果父类方法抛出的异常类型大于父类方法抛出的异常类型,程序就会报错,如下图所示:此时正确的解决方法是保持父类和子类抛出的异常类型相同,如下图所示:注4:方法名必须一致。如果子类重写的方法名不能和父类保持一致,程序也会报错,如下图:注意5:方法的参数类型和个数必须保持一致类型和个数子类中方法参数的of必须和父类方法一致,否则会报错,如下图。InconsistentparametertypesofmethodsInconsistentparametertypesofmethodsInconsistentnumberofparametersinmethods摘要本文介绍了Java中的方法重写(Override)是在子类中重新定义父类已有方法的过程。它是多态性在面向对象程序设计中的具体体现。我们可以使用@Override关键字来重写父类中的一个方法,但是在重写过程中需要注意以下五个问题:子类方法的权限控制字符不能减少;子类方法返回的类型只能更小;子类抛出的异常类型只能归约;子类的方法名必须与父类一致;子类方法的参数类型和数量必须与父类一致。参考资料:《码出高效》判断是非自己,听别人说,得失看数字。公众号:Java面试真题解析
