Drink.COFFEE.getGroupName();
Drink.COFFEE.COLUMBIAN.getLabel();
First off, that sample code you gave violates the "law of demeter" somewhat - as the COLUMBIAN instance field is only used to retrieve the label. Also, with that structure, COLUMBIAN has to be an instance of the COFFEE enum, but I don't think that's what you're really going for here.
someMethod(Drink type)
someOtherMethod(DrinkTypeInterface type)
someMethod(Drink.COFFEE)
someOtherMethod(Drink.COFFEE.COLUMBIAN)
What I'm gathering from what your sample is, is that you want to have an enumeration that contains a "group type" of what the actual drink is, and then each one has individual values for the specific type of drink. Your example gives Coffee, but Tea should work just as well.
The problem is how you've placed your enumerations. As I said before, you'd have to make COLUMBIAN an INSTANCE of the COFFEE enumeration, but that's not really the best way to structure this.
The problem is that you've got Drink, then Coffee/Tea, and then their individual types.
But, if you think about it, although HerbalTea IS A Tea, it is also a DRINK - so it doesn't belong as simply an instance of a TEA.
But, if you make the drink type an enum in and of itself, you get what you wanted, and the structure becomes clearer. And due to interfaces and the power of delegation, both the drink type and the drink enum can be processed in the same manner, as with the following example program:
public final class DrinkEnumExample {
public interface DrinkTypeInterface {
String getDisplayableType();
}
public static enum DrinkType implements DrinkTypeInterface {
COFFEE("Coffee"), TEA("Tea");
private final String type;
private DrinkType(final String type) {
this.type = type;
}
public String getDisplayableType() {
return type;
}
}
public static enum Drink implements DrinkTypeInterface {
COLUMBIAN("Columbian Blend", DrinkType.COFFEE),
ETHIOPIAN("Ethiopian Blend", DrinkType.COFFEE),
MINT_TEA("Mint", DrinkType.TEA),
HERBAL_TEA("Herbal", DrinkType.TEA),
EARL_GREY("Earl Grey", DrinkType.TEA);
private final String label;
private final DrinkType type;
private Drink(String label, DrinkType type) {
this.label = label;
this.type = type;
}
public String getDisplayableType() {
return type.getDisplayableType();
}
public String getLabel() {
return label;
}
}
public DrinkEnumExample() {
super();
}
public static void main(String[] args) {
System.out.println("All drink types");
for (DrinkType type : DrinkType.values()) {
displayType(type);
System.out.println();
}
System.out.println("All drinks");
for (Drink drink : Drink.values()) {
displayDrink(drink);
System.out.println();
}
}
private static void displayDrink(Drink drink) {
displayType(drink);
System.out.print(" - ");
System.out.print(drink.getLabel());
}
private static void displayType(DrinkTypeInterface displayable) {
System.out.print(displayable.getDisplayableType());
}
}
The output of this program is as follows:
All drink types
Coffee
Tea
All drinks
Coffee - Columbian Blend
Coffee - Ethiopian Blend
Tea - Mint
Tea - Herbal
Tea - Earl Grey
Now then, if for some reason you didn't want all your drinks in a single enum, then I didn't understand what you were going for. In that case, if you do have functionality that spans the enums, make separate Coffee and Tea (and whatever) enumerations and apply the interface on both (or more) enumerations. But, I think you were trying to group them like this.