重新定义来自超类(父类)继承的类中的实例方法称为方法覆盖。
现在来看看,类A
和类B
的以下声明,覆盖了 print()
方法 :
public class A { public void print() { System.out.println("A"); } } public class B extends A { public void print() { System.out.println("B"); } }
类B
是类A
的子类。类B
从其超类继承print()
方法并重新定义它。类B
中的print()
方法覆盖类A
的print()
方法。
如果一个类覆盖了一个方法,它会影响覆盖的类及其子类。 考虑下面的类C
的声明:
public class C extends B { // Inherits B.print() }
类C
不声明任何方法。但它继承类B
中的print()
方法。看看下面的代码,猜想它输出结果应该是什么?
class A { public void print() { System.out.println("A"); } } class B extends A { public void print() { System.out.println("B"); } } class C extends B { public void print() { System.out.println("B"); } } public class Main { public static void main(String[] args) { // Create an object of the Manager class A aObj = new A(); B bObj = new B(); C cObj = new C(); aObj.print(); bObj.print(); cObj.print(); } }
执行上面的代码,得到以下输出结果 -
A B B
注意, 类总是继承它的直接超类的方法。
方法必须是实例方法。 覆盖不适用于静态方法。重写方法必须具有与重写方法相同的名称。重写方法必须具有与重写方法相同顺序的相同类型和相同数量的参数。
当方法的参数使用通用类型时,与其他方法比较时考虑将泛型类型参数的擦除。参数的名称是无关紧要的,不会影响方法的覆盖。
覆盖方法的访问级别必须至少与被覆盖方法的访问级别相同或更宽松。下表列出了覆盖方法允许的访问级别 -
覆盖方法访问级别 | 允许覆盖方法访问级别 |
---|---|
public | public |
protected | public, protected |
package-level | public, protected, package-level |
方法可以在其throws子句中包括检查异常的列表。覆盖方法无法向覆盖方法中的异常列表添加新的异常。
它可以删除一个或所有异常,或者可以用另一个异常替换异常。
从子类访问重写的方法。在子类中可以使用关键字super
作为限定符来调用超类的重写方法。
class MySuperClass { public void print() { System.out.println("Inside MySuperClass"); } } class MySubClass extends MySuperClass { public void print() { // Call print() method of MySuperClass class super.print(); // Print a message System.out.println("Inside MySubClass.print()"); } public void callOverridenPrint() { // Call print() method of MySuperClass class super.print(); } } public class Main { public static void main(String[] args) { MySubClass aoSub = new MySubClass(); aoSub.print(); aoSub.callOverridenPrint(); } }
上面的代码生成以下结果。
Inside MySuperClass Inside MySubClass.print() Inside MySuperClass