What you can do is have enums that implement a common interface, and then utilize those interfaces:
public interface YourEnumInterface<E extends Enum<E> & YourEnumInterface<E>> {
//methods that your enum should be implementing
}
The extension for the interface generic declaration is there to guarantee it is only called by enums that implement your interface
And then any enum you have to specify can implement it like so:
public enum MyEnum implements YourEnumInterface<MyEnum> {
// enum constants
TEST_VALUE;
// implementation of interface methods
}
From there, you would simply work with the YourEnumInterface
as an object, and you can pass enum values for them:
public void doSomething(YourEnumInterface enm) {
//work with enm
}
//Elsewheres...
doSomething(MyEnum.TEST_VALUE);
It should be noted, that once you lower your enum down to the interface itself, you won't be able to change the constant you are working with (without casting, which can potentially be unsafe). This should really be used more or less for passing things to a destination that just works with the values (like a config enum, or internalization of strings, etc)
So in relevance to forcing a subclass to implement it:
public class YourSuperClass {
public abstract YourEnumInterface symbol;
}
A runnable example
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;
}
}
The output of this progam is:
1
2
And you can simply get the class' specified enum constant via getEnum
, which they will return their own internal enum.
However, once downcasted to the super type, e.g. YourSuperClass intc = clazz;
, then you will lose this ability to specify the enum itself. Depending on how you store your instances will determine whether or not this requires changes.