我有一个抽象类(或接口)。在这个类中,我想定义一个枚举,以强制扩展这个抽象类(或实现这个接口)的类声明一个具有相同名称的枚举。
abstract class Operator {
public abstract enum Symbol;
public Symbol value;
}
class Binary extends Operator {
public enum Symbol {
pls,
min,
mul,
div,
//...
}
}
class Unary extends Operator {
public enum Symbol {
sin,
cos,
tan,
cot,
//...
}
}
假设我无法知道子类枚举的值。我希望每个扩展类都有一个带有该名称及其值的枚举。我想使用枚举(特别是因为它很容易切换枚举)
答案 0 :(得分:2)
没有办法做这件事,而且,即使它是,你将如何调用子类的实现?我的意思是,只有方法调用可以是虚拟,即在运行时调度。类型不能,所以不用反射作弊(无论如何都抛弃任何类型的安全性,这样你甚至不需要子类),你将无法调用重写的类型(事实上) ,类型不能被覆盖)。
也许你仍然可以通过使用作文来实现你的目标:
public abstract class Operator<T extends Enum<T>> {
public final Class<T> symbol;
public Operator(Class<T> symbol) { this.symbol = symbol; }
}
public enum BinarySymbol { PLS, MIN, MUL, DIV }
public class Binary extends Operator<BinarySymbol> {
public Binary(Object operand1, Object operand2, BinarySymbol symbol) {
super(symbol);
}
}
您的基类Operator
可以通过Class.getEnumConstants()
答案 1 :(得分:-1)
您无法在编译时强制执行此操作。一种方法是在运行时使用反射来查看该类是否已正确实现。我不建议这样做,但这是可能的。
答案 2 :(得分:-1)
你可以做的是拥有实现通用接口的枚举,然后利用这些接口:
public interface YourEnumInterface<E extends Enum<E> & YourEnumInterface<E>> {
//methods that your enum should be implementing
}
接口通用声明的扩展是为了保证它只由实现接口的枚举调用
然后你必须指定的任何枚举都可以这样实现它:
public enum MyEnum implements YourEnumInterface<MyEnum> {
// enum constants
TEST_VALUE;
// implementation of interface methods
}
从那里开始,您只需使用YourEnumInterface
作为对象,就可以为它们传递枚举值:
public void doSomething(YourEnumInterface enm) {
//work with enm
}
//Elsewheres...
doSomething(MyEnum.TEST_VALUE);
应该注意的是,一旦你将枚举降低到接口本身,你将无法改变你正在使用的常量(没有强制转换,这可能是不安全的)。这应该或多或少地用于将事物传递到只与值一起使用的目的地(如配置枚举或字符串内部化等)
因此,与强制子类实现它相关:
public class YourSuperClass {
public abstract YourEnumInterface symbol;
}
public class EnumMagic {
public static void main(String[] args) {
YourSubClass clazz = new YourSubClass();
//prints the default value
System.out.println(clazz.getEnum().getValue());
//gets the value of a specified enum constant
System.out.println(clazz.getEnum().SECOND_TEST.getValue());
}
}
abstract class YourSuperClass {
protected YourEnumInterface symbol;
public abstract YourEnumInterface getEnum();
}
interface YourEnumInterface<E extends Enum<E> & YourEnumInterface<E>> {
public int getValue();
}
class YourSubClass extends YourSuperClass {
public enum MyEnum implements YourEnumInterface<MyEnum> {
TEST_VALUE(1),
SECOND_TEST(2);
private final int val;
private MyEnum(int example) {
this.val = example;
}
public int getValue() {
return this.val;
}
}
public YourSubClass() {
this.symbol = MyEnum.TEST_VALUE;
}
public MyEnum getEnum() {
return MyEnum.TEST_VALUE;
}
}
这个程序的输出是:
1
2
你可以通过getEnum
简单地让类'指定枚举常量,它们将返回它们自己的内部枚举。
然而,一旦下传到超级类型,例如YourSuperClass intc = clazz;
,那么你将失去指定枚举本身的能力。根据您存储实例的方式,将确定是否需要更改。