Menu
CoddyTech

抽象类与抽象方法

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

有时,你想定义一个用作蓝图、但永远不应直接实例化的类。例如,通用的 Shape 类适合作为父类,但没有具体形状的“形状”会是什么样子?这时就需要用到抽象类。

抽象类使用 abstract 关键字声明,不能实例化。它可以包含有实现的普通方法,也可以包含没有方法体的抽象方法:

public abstract class Shape {
    protected String color;
    
    public Shape(String color) {
        this.color = color;
    }
    
    // 抽象方法:没有具体实现
    public abstract double getArea();
    
    // 普通方法:有具体实现
    public String getColor() {
        return color;
    }
}

抽象方法声明子类必须做什么,但不声明如何做。任何继承抽象类的非抽象类都必须为所有抽象方法提供实现:

public class Circle extends Shape {
    private double radius;
    
    public Circle(String color, double radius) {
        super(color);
        this.radius = radius;
    }
    
    @Override
    public double getArea() {
        return Math.PI * radius * radius;
    }
}

你仍然可以将抽象类用作引用类型,从而实现多态:

Shape shape = new Circle("red", 5.0);
System.out.println(shape.getArea());  // 调用 Circle 的实现

当子类共享一些代码,但必须以不同方式实现某些行为时,抽象类就很适用。它们既能规定契约,又能复用代码。

challenge icon

挑战

简单

让我们构建一个家电系统,展示抽象类的强大之处。你将创建一个基础 Appliance 类,定义每种家电都必须执行的操作,同时让具体的家电类型自行决定如何执行。

你将把代码分成四个文件:

  • Appliance.java:创建一个抽象类,作为所有家电的蓝图。每种家电都有一个 brand 字段(String)和一个 wattage 字段(int)。添加一个用于初始化这两个字段的构造函数、分别获取这两个字段的 getter 方法,以及一个返回 [brand] - [wattage]W 的普通方法 getInfo()。定义一个抽象方法 operate(),子类必须实现它,用来表示每种家电如何执行其主要功能。
  • WashingMachine.java:创建一个继承自 Appliance 的具体类。洗衣机有一个额外的 capacity 字段(int),表示以 kg 为单位的装载量。使用 super 处理父类的初始化。实现 operate() 方法,输出:[brand] washing machine is washing [capacity]kg of clothes
  • Microwave.java:创建另一个继承自 Appliance 的具体类。微波炉有一个 power 字段(int),表示功率百分比。实现 operate() 方法,输出:[brand] microwave is heating at [power]% power
  • Main.java:使用多态把所有内容整合起来。你将收到五个输入:一个品牌名称、功率值、洗衣机容量、另一个品牌名称,以及微波炉功率级别。创建一个 WashingMachine 和一个 Microwave,然后将它们存入一个由 Appliance 引用组成的数组中。遍历这个数组,对每种家电,先使用 getInfo() 输出其信息,再调用 operate()。

你将按以下顺序收到五个输入:第一个品牌(String)、第一个功率值(int)、以 kg 为单位的容量(int)、第二个品牌(String)和功率级别(int)。

输出应包含四行,每种家电各占两行,先显示信息,再显示其操作行为。注意,抽象类让你能够统一处理不同的家电,同时每种家电都能以自己独特的方式运行!

亲手试试

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // 读取输入
        String brand1 = scanner.nextLine();
        int wattage1 = scanner.nextInt();
        int capacity = scanner.nextInt();
        scanner.nextLine(); // 读取并跳过换行符
        String brand2 = scanner.nextLine();
        int power = scanner.nextInt();
        
        // TODO:使用 brand1、wattage1 和 capacity 创建一个 WashingMachine 对象
        
        // TODO:使用 brand2、wattage1(或合适的功率值)和 power 创建一个 Microwave 对象
        
        // TODO:创建一个 Appliance 引用数组,存入这两个对象
        
        // TODO:遍历数组,对每个设备执行以下操作:
        // 使用 getInfo() 打印设备信息
        // 调用 operate()
    }
}
quiz icon自我测试

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

面向对象编程中的所有课

自己练习: Java 在线编译器