跨枚举的重复代码 .. 是否有一种方法可以将公共代码集中在这些枚举中?

Duplicate code across enums .. is there an approach to centralize common code in these enums?

我的项目中有以下 3 个枚举,它们都非常相似。

由于每个枚举至少有 2 个公共字段,即 keycode,有什么方法可以使公共字段成为:

与我的所有枚举共享?无需在每个内部声明。

我知道no extends clause allowed for enum

但是有没有一种优雅的方法来实现这些枚举的公共部分的重用?

public enum CarType {

  SEAT("2000", "001"),
  FIAT("3000", "002");

  String key;

  String code;

  CarType(String key, String code) {
    this.key = key;
    this.code = code;
  }

  public String getKey() {
    return key;
  }
  public String getCode() {
    return code;
  }
}

public enum TruckType {

  MERCEDES("4000", "001"),
  FORD("5000", "002");

  String key;

  String code;

  TruckType(String key, String code) {
    this.key = key;
    this.code = code;
  }

  public String getKey() {
    return key;
  }
  public String getCode() {
    return code;
  }
}

public enum VanType {

  JEEP("6000", "001", "40"),
  KIA("7000", "002", "50");

  String key;

  String code;

  String tankSize;

  VanType(String key, String code, String tankSize) {
    this.key = key;
    this.code = code;
    this.tankSize = tankSize;
  }

  public String getKey() {
    return key;
  }
  public String getCode() {
    return code;
  }
  public String getTankSize() {
    return tankSize;
  }
}

Enum - 是一种非常受限的特殊类型 class。你可能会认为 enum constants 就好像它们是 public static final 字段(注意:显式修饰符是不允许使用枚举常量).

这实际上类似于 单例模式

所有枚举常量都急切地在枚举被加载到内存中时初始化。这是 单例 最简单的实现,当一个实例(在本例中是实例)在它的字段的任何静态方法可以被初始化之前被初始化被访问。

我的想法是引入一个 abstract class VehicleType,它将包含两个字符串字段 keycode构造函数getters.

并且每个 enum 将变成 具体 class 扩展 VehicleType class.除了这些 class 中的 构造函数 static final 字段 之外,我们只需要声明一个 VanType 中的字段 并为其提供 getter

它的代码看起来像那样。

public abstract class VehicleType {
    protected String key;
    protected String code;

    public VehicleType(String key, String code) {
        this.key = key;
        this.code = code;
    }

    // getters + common behaviour
}
public class CarType extends VehicleType {
    public static final CarType SEAT = new CarType("2000", "001");
    public static final CarType FIAT = new CarType("3000", "002");

    private CarType(String key, String code) {
        super(key, code);
    }
}
public class TruckType extends VehicleType {
    public static final TruckType SEAT = new TruckType("4000", "001");
    public static final TruckType FIAT = new TruckType("5000", "002");

    private TruckType(String key, String code) {
        super(key, code);
    }
}
public class VanType extends VehicleType {
    public static final VanType JEEP = new VanType("6000", "001", "40");
    public static final VanType KIA = new VanType("7000", "002", "50");

    private String tankSize;

    private VanType(String key, String code, String tankSize) {
        super(key, code);
        this.tankSize = tankSize;
    }

    public String getTankSize() {
        return tankSize;
    }
}