Java抽象类:半成品的模板
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后备箱");
}
}
最佳实践
- 合理使用抽象类:当多个类有共同的状态和行为时使用
- 模板方法模式:将不变的步骤放在抽象类中,可变的步骤由子类实现
- 控制抽象层次:抽象层次不宜过深
- 构造方法链:确保父类构造方法被正确调用
总结
抽象类是Java面向对象设计的重要工具,它通过模板方法模式提供了代码复用和扩展的机制。合理使用抽象类可以提高代码的可维护性和可扩展性。