Reputation: 191
I'm attempting to have 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 make use of this elsewhere by enforcing both that a variable is a Enum and implements the interface. So something along the lines of..
bar(Enum<? extends Fooable> fe)
{
fe.ordinal();
fe.someCommonMethod();
}
However, so far I seem to have to cast fe in order to treat it as implementing the interface, i.e.,
bar(Enum<? extends Fooable> fe)
{
fe.ordinal();
((Fooable)fe).someCommonMethod();
}
and while this should be safe... it seems suboptimal and that I may be overlooking something. Of course if I try to just pass the param as a Fooable then I wind up casting to treat it as a Enum and not only is this no-gain I'm now not even safe. See following:
bar(Fooable fe)
{
// potentially unsafe cast!
((Enum<?>)fe).ordinal();
fe.someCommonMethod();
}
Is there anything I'm overlooking or is the
Enum<? extends Fooable>
about as close to a 'good' solution as I'll get?
I am relatively new to Java and am still catching myself trying to use it like C or C++ so if I'm treating it like a hammer instead of a saw or overlooking something stupidly simple feel free to point it out :)
Upvotes: 11
Views: 6307
Reputation: 5624
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();
}
Upvotes: 21
Reputation: 18397
One option you have is to add any of the methods from Enum you need onto 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've done this you can use FooableEnum
as the parameter type in your method signature and not worry about any of the generic stuff.
Upvotes: 1