Skip to content

Java 继承、重写与重载

继承是面向对象编程的基石之一,它允许我们创建分层的类结构,实现代码重用。与继承紧密相关的是方法重写(Overriding),而另一个容易混淆的概念是方法重载(Overloading)。本章将详细解释这三者的关系与区别。

继承 (Inheritance)

继承允许一个类(子类)获取另一个类(父类)的非私有属性和方法。子类可以像使用自己的成员一样使用父类的成员。

  • 父类 (Superclass): 也叫基类,是被继承的类。
  • 子类 (Subclass): 也叫派生类,是继承自父类的类。

在 Java 中,使用 extends 关键字实现继承。

java
// 父类
public class Vehicle {
    String brand;

    public void start() {
        System.out.println("交通工具启动了!");
    }
}

// 子类 Car 继承自 Vehicle
public class Car extends Vehicle {
    String model;

    public void honk() {
        System.out.println("嘀嘀!汽车在鸣笛。");
    }
}

// 使用
Car myCar = new Car();
myCar.brand = "Toyota"; // 访问从父类继承的属性
myCar.model = "Camry";
myCar.start(); // 调用从父类继承的方法
myCar.honk();  // 调用子类自己的方法

super 关键字

super 关键字用于从子类中引用其直接父类的成员。

  1. 调用父类的构造方法: super() 必须是子类构造方法的第一行语句,用于调用父类的构造方法。
  2. 调用父类的方法: super.methodName() 可以用来调用被子类重写了的父类版本的方法。
java
public class Animal {
    String name;

    public Animal(String name) {
        this.name = name;
        System.out.println("Animal 的构造方法被调用");
    }

    public void eat() {
        System.out.println(name + " 正在吃东西");
    }
}

public class Dog extends Animal {
    public Dog(String name) {
        super(name); // 1. 调用父类的构造方法
        System.out.println("Dog 的构造方法被调用");
    }

    @Override
    public void eat() {
        super.eat(); // 2. 调用父类的 eat() 方法
        System.out.println(name + " 正在啃骨头");
    }
}

方法重写 (Method Overriding)

当子类不满意父类提供的某个方法的实现时,可以提供一个属于自己的、同名同参数的方法版本,这个过程就叫方法重写

重写的规则:

  • 方法名、参数列表必须与父类完全相同。
  • 子类的返回类型必须与父类的返回类型相同或是其子类。
  • 子类方法的访问修饰符不能比父类方法的更严格(例如,父类是 public,子类不能是 protected)。
  • 推荐使用 @Override 注解,它可以让编译器检查这是否一个有效的重写。
java
class Shape {
    public void draw() {
        System.out.println("绘制一个形状");
    }
}

class Circle extends Shape {
    @Override // 告诉编译器,我要重写父类的方法
    public void draw() {
        System.out.println("绘制一个圆形 ○");
    }
}

方法重载 (Method Overloading)

方法重载是指在同一个类中,可以有多个同名的方法,只要它们的参数列表不同(参数的数量、类型或顺序不同)。重载与返回类型无关。

java
public class Printer {
    public void print(String text) {
        System.out.println(text);
    }

    // 重载 print 方法,接受不同类型的参数
    public void print(int number) {
        System.out.println(number);
    }

    // 重载 print 方法,接受不同数量的参数
    public void print(String text, int times) {
        for (int i = 0; i < times; i++) {
            System.out.println(text);
        }
    }
}

重写 (Overriding) vs. 重载 (Overloading)

这是 Java 中一个非常重要的对比,也是面试常见问题。

特性方法重写 (Overriding)方法重载 (Overloading)
目的子类改变父类的行为在一个类中提供多个同名但功能相似的方法
位置发生在父类和子类之间发生在同一个类中
方法签名方法名和参数列表必须相同方法名相同,但参数列表必须不同
返回类型返回类型必须相同或是其子类可以不同
多态性体现了运行时的多态性体现了编译时的多态性
关键字涉及 extendssuper无特定关键字

final 关键字的应用

  • final 方法: 如果父类中的一个方法被声明为 final,那么它不能被任何子类重写

    java
    public class Parent {
        public final void lockMethod() {
            // ...
        }
    }
  • final: 如果一个类被声明为 final,那么它不能被任何类继承。例如,Java 中的 String 类就是 final 的。

    java
    public final class Uninheritable {
        // ...
    }

本站内容仅供学习和研究使用。