跳到主要内容

Java 方法重写

提示
  1. 重写的概念:方法重写发生在继承的子类中,子类定义的方法覆盖超类中具有相同名称和参数的方法。
  2. 使用@Override注解@Override 注解用于明确指示一个方法重写了超类中的方法,有助于减少错误。
  3. 访问修饰符和super关键字:重写方法的访问级别不能比原方法更严格,且可以使用 super 关键字来调用超类中的原始方法。

在上一教程中,我们学习了继承。继承是面向对象编程(OOP)的一个属性,它允许我们从现有的类(超类)派生一个新类(子类)。子类继承了超类的属性和方法。

现在,如果在超类和子类中都定义了同一个方法,那么子类的方法将覆盖超类的方法。这就是所谓的方法重写。

示例 1:方法重写

class Animal {
public void displayInfo() {
System.out.println("我是一只动物。");
}
}

class Dog extends Animal {
@Override
public void displayInfo() {
System.out.println("我是一只狗。");
}
}

class Main {
public static void main(String[] args) {
Dog d1 = new Dog();
d1.displayInfo();
}
}

输出:

我是一只狗。

在上述程序中,displayInfo() 方法同时存在于 Animal 超类和 Dog 子类中。

当我们使用 d1 对象(子类的对象)调用 displayInfo() 时,将调用子类 Dog 中的方法。子类的 displayInfo() 方法重写了超类的同名方法。

Java 中方法重写的工作原理。

注意我们示例中使用了 @Override 注解。在 Java 中,注解是用来向编译器提供信息的元数据。这里,@Override 注解指定编译器该方法重写了超类的方法。

使用 @Override 并非强制性的。然而,当我们使用它时,该方法应遵循重写的所有规则。否则,编译器将生成错误。

Java 重写规则

  • 超类和子类必须具有相同的方法名称、相同的返回类型和相同的参数列表。
  • 我们不能重写被声明为 finalstatic 的方法。
  • 我们应该始终重写超类中的抽象方法(将在后续教程中讨论)。

Java 重写中的 super 关键字

在执行 Java 中的重写时,常见的问题是:

我们能否在重写后访问超类的方法?

答案是可以。要从子类中访问超类的方法,我们使用 super 关键字。

示例 2:使用 super 关键字

class Animal {
public void displayInfo() {
System.out.println("我是一只动物。");
}
}

class Dog extends Animal {
public void displayInfo() {
super.displayInfo();
System.out.println("我是一只狗。");
}
}

class Main {
public static void main(String[] args) {
Dog d1 = new Dog();
d1.displayInfo();
}
}

输出:

我是一只动物。
我是一只狗。

在上面的示例中,子类 Dog 重写了超类 Animal 的方法 displayInfo()

当我们使用 Dog 子类的 d1 对象调用方法 displayInfo() 时,将调用 Dog 子类中的方法;超类中的方法不会被调用。

Dog 子类的 displayInfo() 内部,我们使用了 super.displayInfo() 来调用超类的 displayInfo()

需要注意的是,Java 中的构造器不会被继承。因此,Java 中不存在构造器重写这一概念。

然而,我们可以在其子类中调用超类的构造器。为此,我们使用 super()。要了解更多,请访问 Java super 关键字

方法重写中的访问修饰符

在超类和它的子类中声明的相同方法可以具有不同的访问修饰符。然而,这里有一个限制。

我们只能在子类中使用比超类的访问修饰符提供更大访问权限的访问修饰符。例如,

假设超类中的方法 myClass() 被声明为 protected。那么,在子类中的相同方法 myClass() 可以是 publicprotected,但不能是 private

示例 3:重写中的访问修饰符

class Animal {
protected void displayInfo() {
System.out.println("我是一只动物。");
}
}

class Dog extends Animal {
public void displayInfo() {
System.out.println("我是一只狗。");
}
}

class Main {
public static void main(String[] args) {
Dog d1 = new Dog();
d1.displayInfo();
}
}

输出:

我是一只狗。

在上述示例中,子类 Dog 重写了超类 Animal 的方法 displayInfo()

无论何时我们使用子类的对象 d1 调用 displayInfo(),都会调用子类中的方法。

注意,displayInfo()Animal 超类中被声明为 protected。在 Dog 子类中,相同的方法具有 public 访问修饰符。这是因为 public 提供了比 protected 更大的访问权限。

重写抽象方法

在 Java 中,抽象类被创建为其他类的超类。如果一个类包含抽象方法,则必须重写它。

我们将在后续教程中学习更多关于抽象类和重写抽象方法的内容。