重载与覆盖

重载

重载(overloading)是在一个类里面,方法名称相同,而参数不同。返回类型可以相同也可以不同。

每个重载的方法(包括构造方法)都必须有一个独一无二的参数类型列表。

重载规则:

  • 被重载的方法必须改变参数列表(参数个数或类型不一样)。

  • 被重载的方法可以改变返回类型。

  • 被重载的方法可以改变访问修饰符。

  • 被重载的方法可以声明新的或更广的检查异常。

  • 方法能够在同一个类中或者在一个子类中被重载。

  • 无法以返回值类型作为重载方法的区分标准。

覆盖(又称重写)

覆盖(Override)是子类对父类的允许访问的方法的实现过程进行重新编写,返回值和形参都不能改变。

覆盖的好处在于子类可以根据需要,定义特定于自己的行为,也就是说子类能够根据需要实现父类的方法。

覆盖方法不能抛出新的检查异常或者比被覆盖方法声明更加宽泛的异常。

覆盖规则:

  • 参数列表必须完全于被覆盖方法的相同。

  • 返回类型必须完全于被覆盖方法的返回类型相同。

  • 访问权限不能比父类中被覆盖的方法的访问权限更低。例如:如果父类的一个方法被声明为public,在子类中覆盖该方法就不能声明为protected。

  • 父类的成员方法只能被它的子类覆盖。

  • 声明为final的方法不能被覆盖。

  • 声明为static的方法不能被覆盖,但是能够被再次声明(不使用@Override注解修饰方法)。

  • 子类和父类在同一个包中,子类可以覆盖父类所有方法,除了声明为private和final的方法。

  • 子类和父类不在同一个包中,子类只能够覆盖父类声明为public和protected的非final方法。

  • 覆盖的方法能够抛出任何非强制类异常,无论被覆盖的方法是否抛出异常。但是,覆盖的方法不能抛出新的强制性异常,或者比被覆盖方法声明的更广泛的强制性异常。

  • 构造方法不能被覆盖。

  • 如果不能继承一个方法,则不能覆盖这个方法。

super关键字的使用:当需要在子类中调用父类的被覆盖方法时,需要使用super关键字。

两者的区别与联系

区别点 重载 覆盖
参数列表 必须修改 不能修改
返回类型 可以修改 不能修改
异常 可以修改 可以减少或删除,不能抛出新的或更宽泛的异常
访问 可以修改 不能做更严格的限制(可以降低限制)

方法的重载和覆盖时Java多态性的不同表现,覆盖时父类与子类之间多态性的一种表现,重载可以理解为多态的具体表现形式。