以下是有效的枚举声明.
public enum SomeEnumClass {
ONE(1), TWO(2), THREE(3);
private int someInt;
public SomeEnumClass(int someInt) {
this.someInt = someInt;
}
}
Run Code Online (Sandbox Code Playgroud)
但是我可以用枚举类型覆盖抽象类吗?
SomeEnumClass.java
public abstract enum SomeEnumClass {
private int someInt;
public SomeEnumClass(int someInt) {
this.someInt = someInt;
}
}
Run Code Online (Sandbox Code Playgroud)
OverridingEnumClass.java
public enum OverridingEnumClass extends SomeEnumClass {
ONE(1), TWO(2), THREE(3);
}
Run Code Online (Sandbox Code Playgroud)
如果没有,为什么不呢?什么是好的选择?
chr*_*ke- 37
不,你不能; 枚举类型都是扩展的Enum,它们是隐含的final.枚举可以实现接口,也可以直接在有问题的枚举类中声明相关方法.
(我确实看到了你想要的基本概念,这是一个混合;也许Java 8接口在这方面会更有用.)
在java中,你不能扩展枚举或创建一些抽象枚举甚至生成枚举.如果你想在你的枚举上有一些多态扩展点,你可以应用这样的模式.
让我们说你的枚举
public enum SomeEnumClass {
ONE, TWO, THREE;
}
Run Code Online (Sandbox Code Playgroud)
并且您希望有一些与每个值相关联的行为.但是你不想对每个硬编码,而是希望有能力提供任何其他的.所以你应该声明接口
public interface SomeEnumVisitor<P, R> {
R one(P param);
R two(P param);
R three(P param);
}
Run Code Online (Sandbox Code Playgroud)
然后为每个值添加抽象方法以枚举声明和实现此方法
public enum SomeEnumClass {
ONE {
@Override
public <R, P> R accept(SomeEnumVisitor<R, P> visitor, P param) {
return visitor.one(param);
}
}, TWO {
@Override
public <R, P> R accept(SomeEnumVisitor<R, P> visitor, P param) {
return visitor.two(param);
}
}, THREE {
@Override
public <R, P> R accept(SomeEnumVisitor<R, P> visitor, P param) {
return visitor.three(param);
}
};
public abstract <R, P> R accept(SomeEnumVisitor<R, P> visitor, P param);
}
Run Code Online (Sandbox Code Playgroud)
这样您就可以创建访问者实现以扩展您的枚举行为.例如,在您的情况下,您希望将Integer值与每个枚举值相关联.
public class IntValueVisitor implements SomeClassVisitor<Integer, Void> {
@Override
public Integer one(Void param){
return 1;
}
@Override
public Integer two(Void param){
return 2;
}
@Override
public Integer three(Void param){
return 3;
}
}
Run Code Online (Sandbox Code Playgroud)
最后在您需要的地方使用此访问者
SomeClassEnum something = getAnyValue();
// this expression will return your particular int value associated with particular enum.
int intValue = something.accept(new IntValueVisitor(), null);
Run Code Online (Sandbox Code Playgroud)
当然,如果不适合在枚举内声明所有内容,这种模式适用,例如,如果你在库中有枚举声明并想在主应用程序中扩展枚举行为.或者您只是不想结合枚举定义和实现细节.
为了简化这种模式实现,有一个库可以根据注释生成枚举和访问者,因此您需要在代码中声明所有内容
@AutoEnum(value = {"one", "two", "three"}, name = "SomeEnumClass")
public interface SomeEnumMarker {}
Run Code Online (Sandbox Code Playgroud)
该工具将为您休息.
如果您确实需要“扩展枚举”,则可以使用实际使用类的前 Java 1.5 类型安全枚举模式(请参阅http://www.javacamp.org/designPattern/enum.html的底部),不是枚举。您失去了将 EnumSet 与“枚举”一起使用的能力,并且失去了一些自动生成的方法,例如 items(),但您可以覆盖方法。
一个例子:
// Typesafe enum pattern
public static abstract class Operator {
public static final Operator ADD = new Operator("+") {
@Override
public Double apply(Double firstParam, Double secondParam) {
return firstParam + secondParam;
}
};
public static final Operator SUB = new Operator("-") {
@Override
public Double apply(Double firstParam, Double secondParam) {
return firstParam - secondParam;
}
};
public static final Operator MUL = new Operator("*") {
@Override
public Double apply(Double firstParam, Double secondParam) {
return firstParam * secondParam;
}
};
public static final Operator DIV = new Operator("/") {
@Override
public Double apply(Double firstParam, Double secondParam) {
return firstParam / secondParam;
}
};
private static final Operator[] _ALL_VALUES = {ADD, SUB, MUL, DIV};
private static final List<Operator> ALL_VALUES = Collections.unmodifiableList(Arrays.asList(_ALL_VALUES));
private final String operation;
private Operator(String c) {
operation = c;
}
// Factory method pattern
public static Operator fromToken(String operation) {
for (Operator o : Operator.items())
if (o.operation.equals(operation))
return o;
return null;
}
public Iterable<Operator> items() {
return ALL_VALUES;
}
public abstract Double apply(Double firstParam, Double secondParam);
}
Run Code Online (Sandbox Code Playgroud)