跳转至

抽象类与接口

在掌握了继承和多态的概念后,我们来学习面向对象编程中更高级的特性:抽象类和接口。抽象类是一种特殊的类,可以包含抽象方法和具体方法;接口是一种完全抽象的类,定义了一组方法的规范。它们是实现多态和代码复用的重要工具。

作用

抽象类和接口提供了代码复用的另一种方式,它们允许我们定义通用的行为规范,同时保持实现的灵活性。接口特别适合定义跨继承树的行为规范,而抽象类则适合在具有共同特征的类之间共享代码。

例子

// 抽象类示例
public abstract class Shape {
    // 受保护的属性,允许子类访问
    protected String color;

    // 构造方法
    public Shape(String color) {
        this.color = color;
    }

    // 抽象方法,强制子类实现
    public abstract double getArea();

    // 具体方法,子类可以直接使用
    public void setColor(String color) {
        this.color = 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;
    }
}
// 接口示例
public interface Drawable {
    // 抽象方法
    void draw();

    // 默认方法,实现类可以选择性重写
    default void printInfo() {
        System.out.println("这是一个可绘制的图形");
    }
}
public class Rectangle extends Shape implements Drawable {
    // 私有属性
    private double width;
    private double height;

    // 构造方法
    public Rectangle(String color, double width, double height) {
        super(color);
        this.width = width;
        this.height = height;
    }

    // 实现抽象方法
    @Override
    public double getArea() {
        return width * height;
    }

    // 实现接口方法
    @Override
    public void draw() {
        System.out.println("绘制一个" + color + "的矩形");
    }
}
public class Main {
    public static void main(String[] args) {
        // 抽象类使用
        Shape circle = new Circle("红色", 5.0);
        System.out.println("圆形面积:" + circle.getArea());

        // 接口使用
        Drawable rectangle = new Rectangle("蓝色", 4.0, 6.0);
        rectangle.draw();
        rectangle.printInfo();
    }
}

图表说明

classDiagram
    class Shape {
        # String color
        + Shape(String color)
        + getArea()
        + setColor(String color)
    }

    class Circle {
        - double radius
        + Circle(String color, double radius)
        + getArea()
    }

    class Rectangle {
        - double width
        - double height
        + Rectangle(String color, double width, double height)
        + getArea()
        + draw()
    }

    class Drawable {
        + draw()
        + printInfo()
    }

    Shape <|-- Circle : 继承
    Shape <|-- Rectangle : 继承
    Drawable <|.. Rectangle : 实现

详细说明

  1. 抽象类的特点:

    • 可以包含抽象方法和具体方法,提供部分实现
    • 可以有构造方法,用于初始化
    • 可以有成员变量,存储状态
    • 不能被实例化,只能被继承
    • 子类必须实现所有抽象方法
  2. 接口的特点:

    • 所有方法默认public abstract
    • 所有变量默认public static final
    • 可以多实现,一个类可以实现多个接口
    • Java8支持默认方法和静态方法
    • Java9支持私有方法
  3. 选择建议:

    • 需要共享代码时使用抽象类
    • 需要定义行为规范时使用接口
    • 优先使用接口而不是抽象类
    • 考虑使用组合而不是继承

注意事项

  1. 抽象类不能实例化,只能作为父类
  2. 接口方法默认public abstract
  3. 类优先原则:默认方法冲突时优先使用类中的方法
  4. 接口可以多继承接口
  5. Java9+接口支持私有方法