tags:

views:

528

answers:

4

I'm fairly new to java, and am used to enums essentially beeing nothing more than a named list of integers.

Now I'm writing an implementation where a parent class has a couple of methods that take an enum value as argument. The enum will be defined in child classes, and will differ slightly. Since enums basically seem to behave like classes, this doesn't work the way I expected it to. Each enum defined will be considered a different type of object and the parent class will have to pick one of the defined enums to take as argument.

Is there a good way to make the parent class accept any enum defined in it's child-classes? Or will I have to write a custom class for this?

Edit: Here is my example, fixed as per Jon Skeets answer, for anyone who is looking into how to do this later on:

class Parent {
   protected interface ParentEvent {}
   private HashMap<ParentEvent, String> actions = new HashMap<ParentEvent, String>();

   protected void doStuff(ParentEvent e){

      if(actions.containsKey(e)){
         System.out.println(actions.get(e));
      }

   }
}

class Child extends Parent {
   enum Event implements ParentEvent {EDITED, ADDED, REMOVED}

   public void trigger(){
      doStuff(Event.REMOVED);
   }
}
+5  A: 

You could make your enums implement an interface, then give your parent class method a parameter of that interface type.

As you say, enums are rather different in Java. They're not named numbers - they're a fixed set of values, but those values are object-oriented (i.e. they can use polymorphism etc). Java enums pretty much rock, except for a few tricksy issues around initialization ordering.

Jon Skeet
The only thing that does not exactly rock is that you can't "extend" Enums (say, have a parent Enum, with a given set of constants, and derive this to add more constants...) I implemented a version, so it's doable, but unfortunately not part of the standard toolbox :(
Varkhan
+1  A: 

if i understand you correctly, you want to have a common base class for your enum and want to define several unrelated sets of enums for the sub classes. This is not possible with java's typesafe enums, because they don't allow you to define a base class.

Of course it is not an option just to have one enum defined and always extend its values because this clearly violates the open close principle.

For such a use case I have fairly good experience with Josh Bloch's Typesafe Enum Pattern he describes in Effective Java

Just introduce your super class here and make distinct sub classes for each of enum values your client classes need.

Lars
A: 

I'm not sure, but maybe this is what you want:

public abstract class EnumTest<E extends Enum<E>> {
  public abstract void frobnicate(E value);
}

public class Derived extends EnumTest<Derived.DerivedEnum> {
  public void frobnicate(DerivedEnum value) {
    System.out.println(value);
  }

  public static enum DerivedEnum {
    FOO, BAR,
  }
}
Joachim Sauer
A: 

You could define the enums in their own file if they're applicable to different classes. They don't need to be nested within a class.

You can't extend one set of enums from another though.

It took me a while to get out of the mindset of an enum 'just being an integer'.

izb