我想采取一个现有的enum,并添加更多的元素,如下所示:

enum A {a,b,c}

enum B extends A {d}

/*B is {a,b,c,d}*/

这在Java中可行吗?


当前回答

我自己也有同样的问题,我想把我的观点发表出来。我认为这样做有几个激励因素:

您希望有一些相关的枚举代码,但在不同的类中。在我的例子中,我有一个基类,在一个相关的枚举中定义了几个代码。在以后的某一天(今天!)我想为基类提供一些新功能,这也意味着枚举的新代码。 派生类既支持基类的枚举,也支持它自己的枚举。没有重复的enum值!如何为子类创建一个枚举,包括父类的枚举及其新值。

使用接口并不能真正解决问题:您可能会意外地获得重复的enum值。不可取的。

我最终只是组合了枚举:这确保了不会有任何重复的值,但代价是与相关类的绑定不那么紧密。但是,我认为重复的问题是我主要担心的……

其他回答

我建议你采取另一种方式。

与其扩展现有的枚举,不如创建一个更大的枚举,并创建它的一个子集。 例如,如果你有一个叫PET的枚举,你想把它扩展到ANIMAL,你应该这样做:

public enum ANIMAL {
    WOLF,CAT, DOG
} 
EnumSet<ANIMAL> pets = EnumSet.of(ANIMAL.CAT, ANIMAL.DOG);

注意,pets不是一个不可变的集合,您可能会使用Guava或Java9来提高安全性。

我自己也有同样的问题,我想把我的观点发表出来。我认为这样做有几个激励因素:

您希望有一些相关的枚举代码,但在不同的类中。在我的例子中,我有一个基类,在一个相关的枚举中定义了几个代码。在以后的某一天(今天!)我想为基类提供一些新功能,这也意味着枚举的新代码。 派生类既支持基类的枚举,也支持它自己的枚举。没有重复的enum值!如何为子类创建一个枚举,包括父类的枚举及其新值。

使用接口并不能真正解决问题:您可能会意外地获得重复的enum值。不可取的。

我最终只是组合了枚举:这确保了不会有任何重复的值,但代价是与相关类的绑定不那么紧密。但是,我认为重复的问题是我主要担心的……

我倾向于避免枚举,因为它们是不可扩展的。继续以OP为例,如果A在库中,而B在您自己的代码中,则如果A是枚举,则不能扩展A。这是我有时替换枚举的方法:

// access like enum: A.a
public class A {
    public static final A a = new A();
    public static final A b = new A();
    public static final A c = new A();
/*
 * In case you need to identify your constant
 * in different JVMs, you need an id. This is the case if
 * your object is transfered between
 * different JVM instances (eg. save/load, or network).
 * Also, switch statements don't work with
 * Objects, but work with int.
 */
    public static int maxId=0;
    public int id = maxId++;
    public int getId() { return id; }
}

public class B extends A {
/*
 * good: you can do like
 * A x = getYourEnumFromSomeWhere();
 * if(x instanceof B) ...;
 * to identify which enum x
 * is of.
 */
    public static final A d = new A();
}

public class C extends A {
/* Good: e.getId() != d.getId()
 * Bad: in different JVMs, C and B
 * might be initialized in different order,
 * resulting in different IDs.
 * Workaround: use a fixed int, or hash code.
 */
    public static final A e = new A();
    public int getId() { return -32489132; };
}

有一些陷阱要避免,请参阅代码中的注释。根据您的需要,这是枚举的可靠、可扩展的替代方案。

不,在Java中不能这样做。除此之外,d可能是A的一个实例(考虑到“extends”的正常思想),但只知道A的用户不会知道它——这就违背了枚举是一组已知值的观点。

如果你能告诉我们更多关于你想如何使用它,我们可能会建议其他解决方案。

对此,推荐的解决方案是可扩展枚举模式。

这涉及到创建一个接口,并在当前使用枚举的位置使用该接口。然后使枚举实现接口。通过添加扩展接口的附加enum/类,可以添加更多常量。大致是这样的:

public interface TrafficLights {
  public abstract String getColour();
}
public enum StandardTrafficLights implements TrafficLights {
  RED, YELLOW, GREEN;
  public String getColour() {
    return name();
  }
}
public enum WeirdTrafficLights implements TrafficLights {
  DOUBLE_RED;
  public String getColour() {
    return name();
  }
}

注意,如果你想要TrafficLights.valueof(String)这样的东西,你必须自己实现它。