Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using nested enum types in Java

I have a data structure in mind that involves nested enums, such that I could do something like the following:

Drink.COFFEE.getGroupName(); Drink.COFFEE.COLUMBIAN.getLabel(); 

And if there were method declarations:

someMethod(Drink type) someOtherMethod(DrinkTypeInterface type) 

Then I could say (appropriately):

someMethod(Drink.COFFEE) someOtherMethod(Drink.COFFEE.COLUMBIAN) 

This is what I came up with:

public enum Drink {      COFFEE("Coffee");      private String groupName;      private Drink(String groupName) {         this.groupName = groupName;     }      public enum Coffee implements DrinkTypeInterface {          COLUMBIAN("Columbian Blend"),         ETHIOPIAN("Ethiopian Blend");          private String label;          private Coffee(String label) {             this.label = label;         }          public String getLabel() {             return this.label;         }     }      String getGroupName() {         return this.groupName;     } } 

And the interface:

public interface DrinkTypeInterface {      public String getLabel(); } 

I think I'm just trying to wrap my head around what the best way to do this sort of thing is in Java, or if I need to write a bunch of if-statements to deal with the individual Drink.values(). Any help?

like image 514
Chris Avatar asked Sep 04 '11 00:09

Chris


People also ask

Can we have nested enums in Java?

Enums can be defined as members of a class aka 'nested enum types'.

How do you create multiple enums in Java?

we should do the following steps to have an enum with different values: Create enum constructor which accepts multiple values. Assign each constructor argument to a member field in the enum definition. Create getter methods so we can access any of the values assigned to a particular enum constant.

Can enums inherit Java?

Java Enum and Interface As we have learned, we cannot inherit enum classes in Java. However, enum classes can implement interfaces.

Can enum have methods Java?

The enum class body can include methods and other fields. The compiler automatically adds some special methods when it creates an enum. For example, they have a static values method that returns an array containing all of the values of the enum in the order they are declared.


1 Answers

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.

like image 125
MetroidFan2002 Avatar answered Oct 03 '22 02:10

MetroidFan2002