Menu
CoddyTech

单继承与多层继承

本课属于 Coddy Java 学习旅程的“面向对象编程”单元。第 25 课,共 87 课。

到目前为止,我们已经看到类直接继承一个父类。但根据类之间的关系,继承可以形成不同的结构。让我们来了解两种主要模式:单继承和多级继承。

单继承是我们一直在使用的方式。一个类直接继承且只继承一个父类:

public class Animal { }
public class Dog extends Animal { }
public class Cat extends Animal { }

这里,Dog 和 Cat 都继承自 Animal,但它们彼此之间没有继承关系。每个子类都有一个直接父类。

多层继承会形成一个链条:一个类继承另一个类,而后者本身又继承另一个类:

public class Animal {
    public void eat() {
        System.out.println("Eating");
    }
}

public class Mammal extends Animal {
    public void breathe() {
        System.out.println("Breathing");
    }
}

public class Dog extends Mammal {
    public void bark() {
        System.out.println("Barking");
    }
}

在这个继承链中,Dog 继承自 Mammal,而 Mammal 继承自 Animal。Dog 对象可以访问整个继承链中的所有方法:

Dog dog = new Dog();
dog.eat();      // 来自 Animal 类
dog.breathe();  // 来自 Mammal 类
dog.bark();     // 来自 Dog 类

记住,Object 位于每条继承链的顶端。因此,我们的 Dog 实际上有四个层级:Object -> Animal -> Mammal -> Dog。创建新对象时,构造函数链式调用会经过所有这些层级。

challenge icon

挑战

简单

让我们构建一个交通工具继承层级,展示单继承和多级继承模式。你将创建一系列类,每一层都会增加新功能,展示方法如何通过多个层级继承。

你需要将代码分布在四个文件中:

  • Vehicle.java:创建继承层级顶端的基类。每种交通工具都应具有:
    • 一个用于存储 brand(String)的私有字段
    • 一个接收品牌名称的构造函数
    • 一个返回品牌名称的方法 getBrand()
    • 一个输出 [brand] is moving 的方法 move()
  • LandVehicle.java:创建一个继承自 Vehicle 的类,作为多级继承链的中间层。陆地交通工具会增加地面行驶相关的行为:
    • 一个用于存储 wheels(int)的私有字段
    • 一个接收品牌名称和车轮数的构造函数,并使用 super(brand) 初始化父类部分
    • 一个返回车轮数的方法 getWheels()
    • 一个输出 [brand] honks! 的方法 honk()
  • Car.java:创建一个继承自 LandVehicle 的类,完成三层继承链。汽车会增加自己的专属功能:
    • 一个用于存储 model(String)的私有字段
    • 一个接收品牌名称、车轮数和型号的构造函数,并使用 super(brand, wheels)
    • 一个返回型号的方法 getModel()
    • 一个输出 [brand] [model] with [wheels] wheels 的方法 displayInfo()
  • Main.java:演示 Car 对象如何调用继承层级三个层次中的方法。你会收到三个输入:品牌名称(String)、车轮数(int)和型号(String)。创建一个 Car,并按顺序调用以下方法:
    • move():从 Vehicle(祖父类)继承
    • honk():从 LandVehicle(父类)继承
    • displayInfo():在 Car 类自身中定义

你会收到三个输入:品牌名称、车轮数和型号。

你的输出应包含三行,展示 Car 对象如何使用继承链每一层中的方法,从最顶层的 Vehicle 一直到它自身的类!

亲手试试

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // 读取输入
        String brand = scanner.nextLine();
        int wheels = scanner.nextInt();
        scanner.nextLine(); // 读掉换行符
        String model = scanner.nextLine();
        
        // TODO: 用输入值创建一个 Car 对象
        
        // TODO: 调用 move(),它继承自 Vehicle(祖父类)
        
        // TODO: 调用 honk(),它继承自 LandVehicle(父类)
        
        // TODO: 调用 displayInfo(),它定义在 Car 类中
    }
}
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

面向对象编程中的所有课

自己练习: Java 在线编译器