Skip to content

抽象类

抽象类的定义

抽象类是一种特殊的类,它不能被实例化,只能被继承。在面向对象编程里,抽象类是一个重要的概念,它处于类层次结构的较高位置,为子类提供了一个公共的模板和框架。

抽象类中可以包含抽象方法非抽象方法。这种设计使得抽象类既能够定义一些通用的行为(非抽象方法),又能规定子类必须实现的行为(抽象方法)。

抽象方法是一种没有实现的方法,必须在子类中实现。抽象方法仅定义了方法的签名(包括返回类型、方法名和参数列表),但没有方法体。这意味着抽象方法只是给出了一个“约定”,具体的实现要由子类完成。

抽象父类的所有具体子类都必须为父类的抽象方法提供具体实现;否则其仍然为抽象类。具体子类是指那些可以被实例化的子类。如果一个子类没有实现父类的所有抽象方法,那么这个子类也必须被声明为抽象类。

静态方法私有方法final方法构造方法不能被声明为抽象方法。原因如下:

  • 静态方法:静态方法属于类本身,不依赖于任何实例。抽象方法的目的是为了让子类实现具体的行为,而静态方法不与实例关联,所以不能是抽象的。
  • 私有方法:私有方法只能在定义它的类内部访问,子类无法继承和重写。而抽象方法需要子类来实现,所以私有方法不能是抽象的。
  • final方法:final方法被声明后,不能被子类重写。这与抽象方法要求子类实现的特性相矛盾,所以final方法不能是抽象的。
  • 构造方法:构造方法用于创建对象的实例,不能被继承,也不存在重写的概念。因此,构造方法不能被声明为抽象方法。

示例

java
abstract class Animal {
    protected String name;
    public Animal(String name) {
        this.name = name;
    }
    abstract void speak(); // 抽象方法
    public void getName() {
        System.out.println(name);
    }
}

class Dog extends Animal {
    public Dog(String name) {
        super(name);
    }
    @Override
    void speak() {
        System.out.println("Dog barks");
    }
}

在这个例子中,Animal 是一个抽象类,它有一个抽象方法 speak() 和一个非抽象方法 getName()Dog 类继承自 Animal 类,并实现了 speak() 方法。

更多示例及分析

包含多个抽象方法的抽象类

java
abstract class Shape {
    protected String color;

    public Shape(String color) {
        this.color = color;
    }

    abstract double area(); // 计算面积的抽象方法
    abstract double perimeter(); // 计算周长的抽象方法

    public void displayColor() {
        System.out.println("The color of the shape is: " + color);
    }
}

class Circle extends Shape {
    private double radius;

    public Circle(String color, double radius) {
        super(color);
        this.radius = radius;
    }

    @Override
    double area() {
        return Math.PI * radius * radius;
    }

    @Override
    double perimeter() {
        return 2 * Math.PI * radius;
    }
}

在这个示例中,Shape 是一个抽象类,包含两个抽象方法 area()perimeter(),以及一个非抽象方法 displayColor()Circle 类继承自 Shape 类,并实现了这两个抽象方法。

未完全实现抽象方法的子类

java
abstract class Vehicle {
    protected String brand;

    public Vehicle(String brand) {
        this.brand = brand;
    }

    abstract void start();
    abstract void stop();
}

abstract class Car extends Vehicle {
    public Car(String brand) {
        super(brand);
    }

    @Override
    public void start() {
        System.out.println(brand + " car is starting.");
    }
    // 未实现 stop() 方法,所以 Car 仍然是抽象类
}

class SportsCar extends Car {
    public SportsCar(String brand) {
        super(brand);
    }

    @Override
    public void stop() {
        System.out.println(brand + " sports car is stopping.");
    }
}

在这个示例中,Vehicle 是抽象类,有两个抽象方法 start()stop()Car 类继承自 Vehicle 类,但只实现了 start() 方法,所以 Car 仍然是抽象类。SportsCar 类继承自 Car 类,并实现了 stop() 方法,因此 SportsCar 是具体类,可以被实例化。

意义

抽象类的主要意义在于为子类提供一个公共的类型,并强制子类实现某些方法。具体体现在以下几个方面:

  • 代码复用:抽象类可以包含非抽象方法,这些方法可以被子类继承和复用。子类可以直接使用抽象类中已经实现的方法,避免了代码的重复编写。
  • 规范子类行为:通过定义抽象方法,抽象类规定了子类必须实现的行为。这确保了所有子类都具有一致的接口,提高了代码的可维护性和可扩展性。
  • 多态性:抽象类可以作为一种公共的类型,用于引用子类的对象。这样可以实现多态性,使得代码更加灵活和通用。例如,可以定义一个方法,其参数类型为抽象类,这样该方法可以接受任何继承自该抽象类的子类对象。
java
public class Main {
    public static void main(String[] args) {
        // 使用抽象类引用子类对象
        Shape circle = new Circle("Red", 5);
        circle.displayColor();
        System.out.println("Area: " + circle.area());
        System.out.println("Perimeter: " + circle.perimeter());

        Vehicle sportsCar = new SportsCar("Ferrari");
        sportsCar.start();
        sportsCar.stop();
    }
}

Main 类的 main 方法中,分别使用 Shape 抽象类引用 Circle 对象,使用 Vehicle 抽象类引用 SportsCar 对象,展示了多态性的应用。