在面向对象编程中,方法覆盖是一种语言特性,是多态性的具体体现。它允许子类重新定义父类中已有的方法,子类中的方法名、方法名、参数的类型和个数必须与父类保持一致,这就是方法重写。最简单的方法重写示例如下。定义一个父类Father和一个子类Son。父类中有method方法,子类中会重写method方法。具体实现代码如下。父类Father的实现代码如下:/***parentclass*/classFather{publicvoidmethod(Stringname){System.out.println("Father:"+name);}}父类的method方法在子类中重写了class,具体实现代码如下:/***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("Father:"+name);}}这时候,如果子类重写了父类的方法,定义的权限控制符小于protected,就会报错,如下图:那么问题来了,子类中的accesscontrolcharacter可以变大吗?答案是肯定的,如下图所示:结论:当子类重写父类的方法时,重写的方法访问控制字符不能减少。可以等于或大于父类的权限控制符。注2:子类的返回值类型只能归约。在说这个笔记之前,我们先来看一下前置知识。在Java语言中,Number类是Long的父类。继承关系如下图所示:接下来我们在父类中使用Number类型来表示方法的返回类型:classFather{publicNumbermethod(intnum1,intnum2){returnnum1+num2;}}使用子类Long类型Number类型在子类的实现中,可以正常重复写父类的方法,如下图:当然,如果和父类的返回类型一致也是可以的,如下图所示:但是,如果尝试在子类中增加返回类型,则会报错。如下图所示(Object是Number类型的父类):图片注3:抛出异常的类型只能reduced。如果子类抛出的异常类型变大,也就是子类的方法抛出的异常类型大于父类方法抛出的异常类型,程序就会报错,如下所示如下图:此时正确的解决方法是让父类和子类抛出的异常类型保持一致,如下图:注意事项4:方法名必须一致如果方法名重写为子类不能和父类一致,程序也会报错,如下图:注5:子类中的参数类型和方法个数必须一致方法参数的类型和个数方法必须和父方法保持一致,否则会报错,如下图。Themethodsparametertypesareinconsistent方法的参数个数不一致总结本文介绍的Java中的方法重写(Override)是在子类中重新定义父类已有方法的过程,是一种具体表现面向对象编程中的多态性。我们可以使用@Override关键字重写父类中的一个方法,但是在重写过程中需要注意以下五个问题:子类方法的权限控制字符不能减少;子类方法返回的类型只能子类抛出的异常类型只能归约;子类的方法名必须与父类的方法名一致;子类方法的参数类型和数量必须与父类保持一致。参考资料:《码出高效》
