简体   繁体   中英

Switch between two enum classes at run time in Java

I have two enum classes:

public enum dog{
    Sound("barks"),
    Eat("meat"),
    Drink("water");
    private String attribute;
    private dog (String attribute){
        this.attribute = attribute; }

    public String returnAttribute(){
        return attribute;}
}

And

public enum cat{
    Sound("meows"),
    Eat("fish"),
    Drink("milk");
    private String attribute;
    private cat (String attribute){
        this.attribute = attribute; }

    public String returnAttribute(){
        return attribute;}
}

I would like to switch between the two enums dynamically at runtime as if it's an object(i know it isn't). So I would assign an enum "holder" for dog or cat according to a "condition" then get the attribute value ie enumholder.Sound.returnAttribute;
if dog it will return "barks" if cat it return "meows". Is it possible?

The short answer is no. See, Java enum inheritance

Instead of using enums use classes and inheritance. To do what you are looking for you will need three classes, Animal , Cat , and Dog .

class Animal {
     public String getSound() {
         return "Animal sound";
     }
     // Other mehtods...
}
class Cat extends Animal {
     @Override
     public String getSound() {
         return "Meow";
     }
     // Other mehtods...
}
class Dog extends Animal {
     @Override
     public String getSound() {
         return "Bark";
     }
     // Other mehtods...
}

You could use these classes to get the functionality that you want.

public class Main {
     public static void main(String[] args) {
          Animal a = new Cat();
          System.out.println(a.getSound());
          a = new Dog();
          System.out.println(a.getSound());
     }
}

You seem to just be looking for normal objects. Why do you need enum s?

class AnimalType {
    String sound, eat, drink;
}

// in some method somewhere
AnimalType cat = new AnimalType();
cat.sound = "meows";
cat.eat = "fish";
cat.drink = "milk";

AnimalType dog = new AnimalType();
dog.sound = "barks";
dog.eat = "meat";
dog.drink = "water";

// then use either cat or dog

It looks to me as though you should be modelling this as an interface that your enums inherit - the methods become what you are currently modelling as members. Something like:

interface Animal {
    String getFood();
    int getNumberOfLegs();
}

enum Dog implements Animal {
    POODLE, 
    GOLDEN_RETRIEVER;

    public String getFood() {
        return "dog food";
    }

    public int getNumberOfLegs() {
        return 4;
    }
}

enum Bird implements Animal {
    CANARY("seed"),
    EAGLE("meat");

    private final String food;

    Bird(String food) {
        this.food = food;
    }

    public String getFood() {
        return food;
    }

    public int getNumberOfLegs() {
        return 2;
    }
} 

You can then assign a dog or cat to an Animal variable and it will behave correctly:

Animal animal;
animal = Bird.CANARY;
assertEquals("seed", animal.getFood());
animal = Dog.POODLE;
assertEquals(4, animal.getNumberOfLegs());

This has all the advantages of enum (fixed set of instances with the JVM working out when to construct them) while also being able to treat different sets of animals differently.

If you want to use enum, you should do something like this instead:

public enum AnimalTraits {
    DOG(/*sound*/"barks",
        /*eat  */"meat",
        /*drink*/"water"),
    CAT(/*sound*/"meows",
        /*eat  */"fish",
        /*drink*/"milk");

    private final String sound;
    private final String eat;
    private final String drink;

    private AnimalTraits(String sound, String eat, String drink) {
        this.sound = sound;
        this.eat = eat;
        this.drink = drink;
    }
    public String getSound() {
        return this.sound;
    }
    public String getEat() {
        return this.eat;
    }
    public String getDrink() {
        return this.drink;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM