之路 on it Road.com
方法重写(overriding)规则
重写方法和被重写的方法两者的参数列表必须完全相同, 如果它们不匹配,我们将最终得到一个重载方法。
重写方法的返回类型可以是重写方法中声明的返回类型的子类。
public class SuperClass { //Overriden method public Number sum(Integer a, Integer b) { return a + b; } } class SubClass extends SuperClass { //Overriding method @Override public Integer sum(Integer a, Integer b) { //Integer extends Number; so it's valid return a + b; } }
- 最重要的是,在java中不能以任何方式覆盖私有、静态和最终方法。
public class SuperClass { private Integer sum(Integer a, Integer b) { //private method; overriding not possible return a + b; } } class SubClass extends SuperClass { //Overriding method public Integer sum(Integer a, Integer b) { return a + b; } }
- 重写方法不能抛出比重写方法抛出的层级更高的检查异常。
例如,假设父类中的重写方法抛出FileNotFoundException
,子类中的重写方法可以抛出FileNotFoundException
;但是不允许抛出 IOException
或者 Exception
,因为 IOException
或者 Exception
的层次结构更高,例如:FileNotFoundException
的超类。
更重要的是,我们可以从覆盖方法中省略异常声明。
这是允许的并且完全有效。
此外,覆盖方法可以抛出任何未经检查的(运行时)异常,无论被覆盖的方法是否声明了异常。
public class SuperClass { //Overriden method public Integer sum(Integer a, Integer b) throws FileNotFoundException { return a + b; } } class SubClass extends SuperClass { //Overriding method public Integer sum(Integer a, Integer b) throws IOException { //Not valid; Compile time error return a + b; } //Exception IOException is not compatible with throws clause in SuperClass.sum(Integer, Integer) public Integer sum(Integer a, Integer b) { //It's valid; Don't declare the exception at all is permitted. return a + b; } }
- 还要注意覆盖方法不能减少覆盖方法的访问范围。
简单地说,如果父类中的重写方法是受保护的,那么子类中的重写方法就不能是私有的。
它必须是受保护的(相同的访问权限)或者公共的(更广泛的访问权限)。
public class SuperClass { //Overriden method protected Integer sum(Integer a, Integer b) { return a + b; } } class SubClass extends SuperClass { //Overriding method //Not valid; Compile time error 'Cannot reduce the visibility of the inherited method from SuperClass' private Integer sum(Integer a, Integer b) { return a + b; } }
不再重复,在谈论父类和子类时,方法覆盖是合法的。
它不会发生在同一个类内。
要验证我们是否正确地覆盖了一个方法,只需在覆盖方法上使用注释 @Override。
它将为我们验证所有方法覆盖规则。
如果有任何问题,它将导致编译时错误。
Java 方法重载规则
- 在java中重载方法的第一个也是重要的规则是改变方法签名。
方法签名由参数数量、参数类型和参数顺序组成,如果它们是不同类型的。
public class DemoClass { // Overloaded method public Integer sum(Integer a, Integer b) { return a + b; } // Overloading method public Integer sum(Float a, Integer b) { //Valid return null; } }
- 方法的返回类型从来不是方法签名的一部分,所以只改变方法的返回类型并不构成方法重载。
public class DemoClass { // Overloaded method public Integer sum(Integer a, Integer b) { return a + b; } // Overloading method public Float sum(Integer a, Integer b) { //Not valid; Compile time error return null; } }
- 重载方法时也不考虑方法抛出的异常。
因此,重载方法会抛出相同的异常、不同的异常或者根本不抛出任何异常;对方法加载完全没有影响。
public class DemoClass { // Overloaded method public Integer sum(Integer a, Integer b) throws NullPointerException{ return a + b; } // Overloading method public Integer sum(Integer a, Integer b) throws Exception{ //Not valid; Compile time error return null; } }
日期:2020-09-17 00:10:22 来源:oir作者:oir