← 返回首页

Java抽象类:半成品的模板

📂 java ⏱ 3 min 430 words

Java抽象类:半成品的模板

概述

抽象类是不能被实例化的类,它用于定义子类的通用模板。抽象类可以包含抽象方法(没有实现)和具体方法(有实现),是介于普通类和接口之间的一种设计方式。

1. 抽象类的定义

// 抽象类:图形
public abstract class Shape {
    protected String color;
    protected String name;

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

    // 抽象方法:子类必须实现
    public abstract double area();
    public abstract double perimeter();

    // 具体方法
    public void display() {
        System.out.println("图形: " + name + ", 颜色: " + color);
        System.out.println("面积: " + String.format("%.2f", area()));
        System.out.println("周长: " + String.format("%.2f", perimeter()));
    }
}

2. 抽象类的实现

public class Circle extends Shape {
    private double radius;

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

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

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

public class Triangle extends Shape {
    private double a, b, c;

    public Triangle(String color, double a, double b, double c) {
        super(color, "三角形");
        this.a = a;
        this.b = b;
        this.c = c;
    }

    @Override
    public double area() {
        double s = (a + b + c) / 2;
        return Math.sqrt(s * (s-a) * (s-b) * (s-c));
    }

    @Override
    public double perimeter() {
        return a + b + c;
    }
}

3. 模板方法模式

public abstract class DataProcessor {
    // 模板方法:定义算法骨架
    public final void process() {
        readData();
        processData();
        writeData();
    }

    protected abstract void readData();
    protected abstract void processData();
    protected abstract void writeData();
}

public class CSVProcessor extends DataProcessor {
    @Override
    protected void readData() {
        System.out.println("从CSV文件读取数据");
    }

    @Override
    protected void processData() {
        System.out.println("处理CSV数据");
    }

    @Override
    protected void writeData() {
        System.out.println("写入CSV结果");
    }
}

public class DBProcessor extends DataProcessor {
    @Override
    protected void readData() {
        System.out.println("从数据库读取数据");
    }

    @Override
    protected void processData() {
        System.out.println("处理数据库数据");
    }

    @Override
    protected void writeData() {
        System.out.println("写入数据库结果");
    }
}

4. 抽象类与接口的选择

// 使用抽象类:当需要共享状态和实现
public abstract class AbstractLogger {
    protected String name;
    protected int level;

    public abstract void write(String message);

    public void log(String message) {
        if (message != null && !message.isEmpty()) {
            write(message);
        }
    }
}

// 使用接口:当只需要定义行为契约
public interface Loggable {
    void log(String message);
    default String getTag() {
        return this.getClass().getSimpleName();
    }
}

5. 多层抽象类

public abstract class Vehicle {
    protected String brand;

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

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

public abstract class Car extends Vehicle {
    protected int doors;

    public Car(String brand, int doors) {
        super(brand);
        this.doors = doors;
    }

    public abstract void openTrunk();
}

public class SUV extends Car {
    public SUV(String brand) {
        super(brand, 5);
    }

    @Override
    public void start() {
        System.out.println(brand + " SUV启动");
    }

    @Override
    public void stop() {
        System.out.println(brand + " SUV停止");
    }

    @Override
    public void openTrunk() {
        System.out.println("打开SUV后备箱");
    }
}

最佳实践

  1. 合理使用抽象类:当多个类有共同的状态和行为时使用
  2. 模板方法模式:将不变的步骤放在抽象类中,可变的步骤由子类实现
  3. 控制抽象层次:抽象层次不宜过深
  4. 构造方法链:确保父类构造方法被正确调用

总结

抽象类是Java面向对象设计的重要工具,它通过模板方法模式提供了代码复用和扩展的机制。合理使用抽象类可以提高代码的可维护性和可扩展性。