tags:

views:

2303

answers:

4
+5  Q: 

Java extend enum

Is something like this possible in Java. I want to take an existing enum and add more elements to it

enum A {a,b,c}

enum B extends A {d}

/*B is {a,b,c,d}*/
+4  A: 

No, you can't do this in Java. Aside from anything else, d would then presumably be an instance of A (given the normal idea of "extends"), but users who only knew about A wouldn't know about it - which defeats the point of an enum being a well-known set of values.

If you could tell us more about how you want to use this, we could potentially suggest alternative solutions.

Jon Skeet
The short explanation is that there is an existing enum that I would like to add more elements to, without modifying the original.I was using 'extends' as an illustration of the idea, I didn't intend to restrict myself to the keyword.
Mike
You can't do this for exactly the reason I said before: an enum is meant to be a well-known set of values. If you could add elements to it, any existing code using it could suddenly get a nasty shock.
Jon Skeet
All enums implicitly extend java.lang.Enum. Since Java does not support multiple inheritance, an enum cannot extend anything else.
Gastoni
+1  A: 

Good article here: Creating Java Enum Objects at Runtime

dogbane
In what way 'good'? It seems to confuse increasing the extension of a closed set with the Java 'extends' keyword which denotes a restriction of the extension.
Pete Kirkham
I think he meant 'good' in terms of getting the OP what they wanted. Whether what the OP wants is a good thing or not is certainly up for debate (and I think that most of us would land on the 'not' side of that issue) - but the article does show a way to add values to an enum when one absolutely have to. That said, I shudder to think about the testing that must be done to make sure that it really works, regardless of JVM, etc...
Kevin Day
+1 for answering the question
tylermac
+4  A: 

The recommended solution to this is the extensible enum pattern.

This involves creating an interface and using that where you currently use the enum. Then make the enum implement the interface. You can add more constants by making that new enum also extend the interface.

JodaStephen
+12  A: 

Enums represent a complete enumeration of possible values. So the (unhelpful) answer is no.

As an example of a real problem take weekdays, weekend days and, the union, days of week. We could define all days within days-of-week but then we would not be able to represent properties special to either weekdays and weekend-days.

What we could do, is have three enum types with a mapping between weekdays/weekend-days and days-of-week.

public enum Weekday {
    MON, TUE, WED, THU, FRI;
    public DayOfWeek toDayOfWeek() { ... }
}
public enum WeekendDay {
    SAT, SUN;
    public DayOfWeek toDayOfWeek() { ... }
}
public enum DayOfWeek {
    MON, TUE, WED, THU, FRI, SAT, SUN;
}

Alternatively, we could have an open-ended interface for day-of-week:

interface Day {
    ...
}
public enum Weekday implements Day {
    MON, TUE, WED, THU, FRI;
}
public enum WeekendDay implements Day {
    SAT, SUN;
}

Or we could combine the two approaches:

interface Day {
    ...
}
public enum Weekday implements Day {
    MON, TUE, WED, THU, FRI;
    public DayOfWeek toDayOfWeek() { ... }
}
public enum WeekendDay implements Day {
    SAT, SUN;
    public DayOfWeek toDayOfWeek() { ... }
}
public enum DayOfWeek {
    MON, TUE, WED, THU, FRI, SAT, SUN;
    public Day toDay() { ... }
}
Tom Hawtin - tackline
this is an excellent explanation of the extensible enum pattern. JodaStephen gave it a name, but you provided excellent code examples.
Kevin Day