Java 教程

Java 控制语句

面向对象编程

Java 内置类

Java 文件处理

Java 错误与异常

Java 多线程

Java 同步

Java 网络编程

Java 集合

Java 接口

Java 数据结构

Java 集合算法

高级 Java

Java 杂项

Java API 和框架

Java 类引用

Java 有用资源

Java - 方法重写



在上一章中,我们讨论了超类和子类。如果一个类继承了其超类的方法,那么就有可能重写该方法,前提是该方法没有被标记为 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 reference and object
      Animal b = new Dog();   // Animal reference but Dog object

      a.move();   // runs the method in Animal class
      b.move();   // runs the method in Dog class
   }
}

输出

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 reference and object
      Animal b = new Dog();   // Animal reference but Dog object

      a.move();   // runs the method in Animal class
      b.move();   // runs the method in Dog class
      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 的方法不能被重写,但可以被重新声明。

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

  • 与实例的超类位于同一包中的子类可以重写任何未声明为 private 或 final 的超类方法。

  • 不同包中的子类只能重写声明为 public 或 protected 的非 final 方法。

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

  • 构造函数不能被重写。

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();   // invokes the super class method
      System.out.println("Dogs can walk and run");
   }
}

public class TestDog {

   public static void main(String args[]) {
      Animal b = new Dog();   // Animal reference but Dog object
      b.move();   // runs the method in Dog class
   }
}

输出

Animals can move
Dogs can walk and run
广告