Enum <? extends interfaces>
I am trying to create a collection of enums that extend a common interface, so something like:
interface Fooable { void someCommonMethod(); } enum E1 implements Fooable { // some enumuerations and a definition for someCommonMethod() } enum E2 implements Fooable { // some different enumerations and a different definition for someCommonMethod() } and then use it elsewhere, applying both variables as Enum and implementing the interface. So something like ...
bar(Enum<? extends Fooable> fe) { fe.ordinal(); fe.someCommonMethod(); } However, so far I seem to have had to drop fe to treat it as an implementation of an interface, i.e.
bar(Enum<? extends Fooable> fe) { fe.ordinal(); ((Fooable)fe).someCommonMethod(); } and although it should be safe ... it seems suboptimal and that I can ignore something. Of course, if I try to just pass the parameter as Fooable, then I end the casting to consider it as Enum, and not only is it a no-win, I'm not even safe now. See below:
bar(Fooable fe) { // potentially unsafe cast! ((Enum<?>)fe).ordinal(); fe.someCommonMethod(); } Is there anything that I'm missing or is it
Enum<? extends Fooable> about as close to a “good” solution, how do I get?
I'm relatively new to Java, and I'm still trying to use it like C or C ++, so if I see it as a hammer instead of a saw or miss something stupid just feel free to point it out :)
One option is to add any of the methods from Enum that you need to Fooable, or create a new interface that extends Fooable and adds the Enum methods you need.
Example:
interface Fooable { void someCommonMethod(); } interface FooableEnum extends Fooable { int ordinal(); } enum E1 implements FooableEnum { // Implement someCommonMethod. // ordinal() is already implemented by default. } Once you do this, you can use FooableEnum as the parameter type in your method signature and not worry about any of the common things.
This means that T extends Enum and implements Fooable:
<T extends Enum<T> & Fooable> Thus, your method can be written as:
<T extends Enum<T> & Fooable> void bar(T fe) { fe.ordinal(); fe.someCommonMethod(); }