在上一章中,我们讨论了超类和子类。如果一个类从其超类继承了一个方法,那么只要该方法未标记为final,就有机会重写该方法。

Java 中重写的好处

重写的好处是:能够定义特定于子类类型的行为,这意味着子类可以根据其要求实现父类方法。

在面向对象术语,重写是指覆盖现有方法的功能。

Java 方法重写

方法重写允许我们实现运行时多态 用于编写已在超类中定义的子类方法的具体定义。

该方法是超类,并且子类中的重写方法应具有相同的声明签名,例如参数列表、

Java 方法重写的用法

以下是 Java 中方法重写的两个重要用法:

  • 方法重写用于实现运行时多态性。
  • 方法重写用于编写子类方法的具体定义(该方法称为重写方法)。

Java 中方法重写的示例

让我们看一个示例。

class Animal {
   public void move() {
      System.out.println("Animals can move");
   }
}

class Dog extends Animal {
   public void move() {
      System.out.println("Dogs can walk and run");
   }
}

public class TestDog {

   public static void main(String args[]) {
      Animal a = new Animal();   // 动物引用和对象
      Animal b = new Dog();   // 动物引用,Dog 对象

      a.move();   //运行Animal类中的方法
      b.move();   //运行Dog类中的方法
   }
} 

输出

Animals can move
Dogs can walk and run 

在上面的示例中,您可以看到尽管 b 是 Animal 的一种类型,但它在 Dog 类中运行 move 方法。原因是:在编译时,对引用类型进行检查。但是,在运行时,JVM 会计算出对象类型,并运行属于该特定对象的方法。

因此,在上面的示例中,程序将正确编译,因为 Animal 类具有 move 方法。然后,在运行时,它运行特定于该对象的方法。

考虑以下示例 -

示例

class Animal {
   public void move() {
      System.out.println("Animals can move");
   }
}

class Dog extends Animal {
   public void move() {
      System.out.println("Dogs can walk and run");
   }
   public void bark() {
      System.out.println("Dogs can bark");
   }
}

public class TestDog {

   public static void main(String args[]) {
      Animal a = new Animal();   //动物引用和对象
      Animal b = new Dog();   // 动物引用,但 Dog 对象

      a.move();   //运行Animal类中的方法
      b.move();   //运行Dog类中的方法
      b.bark();
   }
} 

输出

TestDog.java:26: error: cannot find symbol
      b.bark();
       ^
  symbol:   method bark()
  location: variable b of type Animal
1 error 

此程序将引发编译时错误,因为 b 的引用类型 Animal 没有名为 bark 的方法。

方法重写规则

  • 参数列表应与重写方法的参数列表完全相同。

  • 返回类型应与声明的返回类型相同或其子类型在超类中的原始重写方法中。

  • 访问级别不能比重写方法的访问级别更严格。例如:如果超类方法被声明为 public,则子类中的重写方法不能为 private 或 protected。

  • 只有当实例方法被继承时,才可以重写实例方法。子类。

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

  • 声明为static的方法不能被覆盖,但可以重新定义-声明。

  • 如果一个方法不能被继承,那么它就不能被重写。

  • 同一包中的子类因为实例的超类可以重写任何未声明为私有或最终的超类方法。

  • 不同包中的子类只能重写声明为公共或受保护的非最终方法。

  • 重写方法可以抛出任何未检查异常,无论被重写方法是否抛出异常。但是,重写方法不应抛出新的或比被重写方法声明的异常更广泛的已检查异常。重写方法可以抛出比被重写方法更窄或更少的异常。

  • 构造函数不能被重写。

Java 方法和构造函数重写

在Java中,每个类都有不同的名称,构造函数的名称与类名称相同。因此,我们无法重写 构造函数,因为它们不能具有相同的名称。

Java 方法重写:使用super 关键字

调用重写方法的超类版本时,使用 super 关键字。

示例:使用 super 关键字

class Animal {
   public void move() {
      System.out.println("Animals can move");
   }
}

class Dog extends Animal {
   public void move() {
      super.move();   //调用超类方法
      System.out.println("Dogs can walk and run");
   }
}

public class TestDog {

   public static void main(String args[]) {
      Animal b = new Dog();   // 动物引用,但 Dog 对象
      b.move();   //运行Dog类中的方法
   }
} 

输出

Animals can move
Dogs can walk and run