文章目录
81. Java 枚举类 - 枚举中的抽象方法
在 Java 枚举中,虽然 枚举不能继承类,但它们可以包含抽象方法,并让每个枚举常量提供自己的实现。🚀
1️⃣ 为什么要在枚举中使用抽象方法?
有时候,不同的枚举值需要执行不同的逻辑。例如:
- 不同的操作符(
+
、-
、*
、/
)有不同的计算方式。 - 不同的订单状态(
NEW
、SHIPPED
、DELIVERED
)有不同的处理逻辑。
💡 普通的 switch
语句可以解决这个问题:
switch (operation) {
case ADD: return a + b;
case SUBTRACT: return a - b;
}
但如果用枚举的抽象方法,代码更优雅、可读性更高!💡
2️⃣ 枚举中的抽象方法示例
enum Operation {
ADD {
@Override
double apply(double x, double y) {
return x + y;
}
},
SUBTRACT {
@Override
double apply(double x, double y) {
return x - y;
}
},
MULTIPLY {
@Override
double apply(double x, double y) {
return x * y;
}
},
DIVIDE {
@Override
double apply(double x, double y) {
return x / y;
}
};
// 定义抽象方法,要求所有枚举常量必须实现
abstract double apply(double x, double y);
}
public class EnumTest {
public static void main(String[] args) {
double result = Operation.MULTIPLY.apply(10, 5);
System.out.println("Multiplication result: " + result);
}
}
💡 输出
Multiplication result: 50.0
📌 代码解析
Operation
枚举代表四种计算操作。- 每个 枚举常量(ADD, SUBTRACT, MULTIPLY, DIVIDE) 都实现了
apply()
方法。 apply()
是抽象方法,所有枚举值都必须提供具体实现。
3️⃣ 代码优化:让 toString()
返回更友好的信息
我们可以重写 toString()
,让枚举在打印时显示符号:
enum Operation {
ADD("+") {
@Override
double apply(double x, double y) {
return x + y;
}
},
SUBTRACT("-") {
@Override
double apply(double x, double y) {
return x - y;
}
},
MULTIPLY("*") {
@Override
double apply(double x, double y) {
return x * y;
}
},
DIVIDE("/") {
@Override
double apply(double x, double y) {
return x / y;
}
};
private final String symbol;
Operation(String symbol) {
this.symbol = symbol;
}
abstract double apply(double x, double y);
@Override
public String toString() {
return symbol;
}
}
public class EnumTest {
public static void main(String[] args) {
double result = Operation.ADD.apply(2, 3);
System.out.println(Operation.ADD + " result: " + result);
}
}
💡 输出
+ result: 5.0
📌 代码优化
- 每个枚举常量存储了自己的
symbol
(+
,-
,\*
,/
)。 - 重写
toString()
让枚举在打印时显示符号,而不是默认的ADD, SUBTRACT
。
4️⃣ 枚举的抽象方法 vs switch
用 switch
语句,我们可以这样写:
double apply(Operation op, double x, double y) {
switch (op) {
case ADD: return x + y;
case SUBTRACT: return x - y;
case MULTIPLY: return x * y;
case DIVIDE: return x / y;
default: throw new AssertionError("Unknown operation: " + op);
}
}
但这样有缺点: ❌ 可读性较差,switch
代码量较多
❌ 扩展性较差,如果要新增 MODULO
操作,必须修改 switch
❌ 违反了面向对象设计原则(“行为” 应该和 “数据” 绑定在一起)
✅ 使用抽象方法,每个枚举值自己定义行为,代码更优雅!
5️⃣ 枚举的抽象方法 vs 普通策略模式
如果不使用枚举,通常我们会用 策略模式(Strategy Pattern):
interface Operation {
double apply(double x, double y);
}
class AddOperation implements Operation {
public double apply(double x, double y) {
return x + y;
}
}
class MultiplyOperation implements Operation {
public double apply(double x, double y) {
return x * y;
}
}
public class StrategyTest {
public static void main(String[] args) {
Operation op = new AddOperation();
System.out.println(op.apply(2, 3)); // 输出 5
}
}
📌 但这种方式有个缺点:
- 需要创建多个类(
AddOperation
,MultiplyOperation
)。 - 代码分散,每个操作是一个单独的类。
✅ 枚举的抽象方法可以让策略模式更优雅!
- 不用创建多个类,所有实现都在 一个
enum
里。 - 更易读,更好维护。
🔹 总结
特性 | 抽象方法的枚举 | switch 语句 | 传统策略模式 |
---|---|---|---|
可读性 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ |
扩展性 | ⭐⭐⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐ |
代码量 | ⭐⭐⭐⭐ | ⭐⭐ | ⭐ |
对象数量 | 1 | 1 | 多个类 |
✅ 推荐使用枚举的抽象方法,代码更优雅、更易维护 🚀
6️⃣ 什么时候使用枚举的抽象方法?
✅ 适合使用的情况
- 不同的枚举值需要不同的行为(如
Operation.ADD.apply()
)。 - 避免
switch
语句,提高可读性。 - 替代传统策略模式,减少类数量。
❌ 不适合使用的情况
- 如果所有枚举值的行为相同,不需要抽象方法(用普通
enum
即可)。 - 如果需要继承其他类,枚举不能继承类(但可以实现接口)。
希望这个讲解能帮你理解 如何在枚举中使用抽象方法!🚀 🎯