Utshaw
Utshaw

Reputation: 4276

Working with enum types in java

I need to create a "super" enum (here ESideItem) which will keep record of "sub" enums (SALAD, FRY, TACO) & I need to access "sub" enum's fields(price) from outside too.
I meant "super" as main type & "sub" as sub-type of that main type.
There can be many types of SideItems (FRY, SALAD, TACO) for a meal & each of these sideitems can be of many types (i.e SALAD can be CHICKEN or AFGHAN or MIMOSA etc).
Following Ray Tayek's answer to this question I've implemented this:

public abstract class SideItem {

public enum FRY {
    FRENCHFRY(25.25f), SEASONEDCURLYFRY(30.10f);

    private float  price;

    FRY(float price) {
        this.price = price;
    }

    public float getPrice() {
        return price;
    }
}

public enum SALAD{
    AFGHANSALAD(50.25f), CHICKENSALAD(40.10f), MIMOSASALAD(45.89f);

    private float  price;

    SALAD(float price) {
        this.price = price;
    }


    public float getPrice() {
        return price;
    }
}

public enum TACO{
    MONSTERTACO(26.25f), NACHOMONSTERTACO(35.10f);

    private float  price;

    TACO(float price) {
        this.price = price;
    }


    public float getPrice() {
        return price;
    }
}

public enum ESideItem {
    FRY(SideItem.FRY.FRENCHFRY), SALAD(SideItem.SALAD.AFGHANSALAD), TACO(SideItem.TACO.MONSTERTACO);

    ESideItem(Enum e) {
        this.e = e;
    }

    public Object[] subValues() {
        return e.getDeclaringClass().getEnumConstants();
    }

    final Enum e;

}
}

I implementd Main.java as follows:

public class Main {

public static void main(String[] args) {

    for(SideItem.ESideItem aSideItem : SideItem.ESideItem.values()){
        System.out.println(aSideItem);
        for(Object o : aSideItem.subValues()){
            System.out.format("%-15s",o);
            System.out.println();
        }

        System.out.println();
    }
}
}

The output is:

FRY
FRENCHFRY      
SEASONEDCURLYFRY

SALAD
AFGHANSALAD    
CHICKENSALAD   
MIMOSASALAD    

TACO
MONSTERTACO    
NACHOMONSTERTACO

Main.java is like client side & SideItem.java is like server side. I can change or add any instance in the ESubItem enum from SideItem.java. Main.java should give output according to that change
But I do need to get price of these individual TACO's, SALAD's, FRY's .
Is there any way to access these fields from Main.java using enum?
If not then what kind of data structure should I use to solve this problem ?

Upvotes: 0

Views: 725

Answers (4)

Michael
Michael

Reputation: 44110

You should be using an interface:

interface Food
{
    float getPrice();
}

public enum Fry implements Food 
{
    FRENCH_FRY(25.25f), SEASONED_CURLY_FRY(30.10f);

    private final float price;

    FRY(float price) {
        this.price = price;
    }

    @Override
    public float getPrice() {
        return price;
    }
}

And the same for the other two...

Then you can compose them like so:

public enum Meal implements Food {
    HAPPY_MEAL(Fry.FRENCH_FRY, Fry.SEASONED_CURLY_FRY),
    SAD_MEAL(Salad.AFGHAN_SALAD);

    private final List<Food> items;

    Meal (Food... items) {
        this.items = Arrays.asList(food);
    }

    @Override
    public float getPrice()
    {
        return (float) items.stream().mapToDouble(Food::getPrice).sum();
    }
}

Upvotes: 2

daniu
daniu

Reputation: 14999

You can define an interface, say

public interface Priced {
    double getPrice();
}

The enums can implement that

public enum FRY implements Priced { // no further change needed, method already there

and you can return an array of Priced with your subValues().

public Priced[] subValues() {
    return Stream.of(FRY.values(), SALAD.values(), TACO.values()).
           toArray(Priced[]::new);
}

I'm not entirely sure if the latter works this way, but being able to implement an interface in your enum is the main point.

Upvotes: 0

piy26
piy26

Reputation: 1592

You will need to something like:

for(Object o : aSideItem.subValues()){
    if(o instanceof SideItem.FRY)
    ((SideItem.FRY)o).getPrice()

Upvotes: 0

Kayaman
Kayaman

Reputation: 73528

If you want to access the price for calculations etc. the easiest way is to make all those enums implement an interface with public float getPrice().

For display purposes you would only need to modify the toString() of each enum.

The enum ESideItem and SideItem classes seem unnecessary though. Especially the ESideItem doesn't seem like it should be an enum at all, and the way you're using getDeclaringClass().getEnumConstants() is just a really bad idea.

Upvotes: 0

Related Questions