我可以用Java制作一个抽象枚举吗?

我可以用Java制作一个抽象枚举吗?,java,enums,Java,Enums,下面是一个有效的枚举声明 public enum SomeEnumClass { ONE(1), TWO(2), THREE(3); private int someInt; public SomeEnumClass(int someInt) { this.someInt = someInt; } } 但是我可以用枚举类型重写抽象类吗 SomeEnumClass.java public abstract enum SomeEnumClass

下面是一个有效的枚举声明

public enum SomeEnumClass {

    ONE(1), TWO(2), THREE(3);

    private int someInt;

    public SomeEnumClass(int someInt) {
        this.someInt = someInt;
    }
}
但是我可以用枚举类型重写抽象类吗

SomeEnumClass.java

public abstract enum SomeEnumClass {

    private int someInt;

    public SomeEnumClass(int someInt) {
        this.someInt = someInt;
    }
}
public enum OverridingEnumClass extends SomeEnumClass {

    ONE(1), TWO(2), THREE(3);

}
覆盖umclass.java

public abstract enum SomeEnumClass {

    private int someInt;

    public SomeEnumClass(int someInt) {
        this.someInt = someInt;
    }
}
public enum OverridingEnumClass extends SomeEnumClass {

    ONE(1), TWO(2), THREE(3);

}

若否,原因为何?如果没有,那么什么是好的选择呢?

不,你不能;枚举类型都扩展了
enum
,它们是隐式的
final
。枚举可以实现接口,也可以直接在相关的枚举类上声明相关方法

(我确实看到了您想要的基本概念,这是一个mixin;也许Java 8接口在这方面会更有用。)

如果您真的需要“扩展一个枚举”,您可以使用Java 1.5之前的Typesafe枚举模式(见的底部),它实际上使用一个类,而不是枚举。您失去了将枚举集与“enum”一起使用的能力,也失去了一些自动生成的方法,如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); 

}
//类型安全枚举模式
公共静态抽象类运算符{
公共静态最终运算符ADD=新运算符(“+”){
@凌驾
公共双应用(双第一参数,双第二参数){
返回firstParam+secondParam;
}
};
公共静态最终运算符SUB=新运算符(“-”){
@凌驾
公共双应用(双第一参数,双第二参数){
返回firstParam-secondParam;
}
};
公共静态最终运算符MUL=新运算符(“*”){
@凌驾
公共双应用(双第一参数,双第二参数){
返回firstParam*secondParam;
}
};
公共静态最终运算符DIV=新运算符(“/”){
@凌驾
公共双应用(双第一参数,双第二参数){
返回firstParam/secondParam;
}
};
私有静态最终运算符[]_ALL_值={ADD,SUB,MUL,DIV};
私有静态最终列表ALL_值=Collections.unmodifiableList(Arrays.asList(_ALL_值));
私有最终字符串操作;
专用操作员(字符串c){
操作=c;
}
//工厂方法模式
公共静态运算符fromToken(字符串操作){
for(运算符o:Operator.items())
如果(o.运算等于(运算))
返回o;
返回null;
}
可供公众查阅的项目(){
返回所有_值;
}
公开摘要双应用(双第一参数,双第二参数);
}

在java中,您不能扩展枚举或创建一些抽象枚举,甚至不能泛化枚举。 如果希望在枚举上有一些多态扩展点,可以应用这样的模式

比如说你的枚举

public enum SomeEnumClass {
    ONE, TWO, THREE;
}
您希望与每个值关联一些行为。但您不想硬编码每一个,而是希望能够提供任何其他。 所以您应该声明接口

public interface SomeEnumVisitor<P, R> {
     R one(P param);
     R two(P param);
     R three(P param);
}
当然,如果不适合在enum中声明所有内容,例如,如果您在库中有enum声明,并且希望在主应用程序中扩展enum的行为,则此模式适用。或者您只是不想将枚举定义和实现细节结合起来

为了简化此模式实现,您需要在代码中声明的所有内容

@AutoEnum(value = {"one", "two", "three"}, name = "SomeEnumClass")
public interface SomeEnumMarker {}

该工具将为您执行其余操作。

enum!=班级。您不能编写
抽象枚举
@MaximShoustin枚举以什么方式不是类?请参见。来吧,不要将
enum
enum
混合使用:)@MaximShoustin那么有什么区别呢?@mcepender幸运的是,
enum
不是任何魔法类型。它们只是扩展
Enum
的类。执行
javap类文件有助于解开谜团。啊,幸运的是,
enum
可以实现
接口。所以我用它作为替代,在这个答案的基础上,不需要抽象的方法来覆盖当前的方法。这意味着您可以保留方法的默认实现,只覆盖需要特别处理的实现。
@AutoEnum(value = {"one", "two", "three"}, name = "SomeEnumClass")
public interface SomeEnumMarker {}