Zhro
Zhro

Reputation: 2614

How to use an enum as one would use an interface?

How can I assign SomeEnum1 or SomeEnum2 to an "enum" which implements SomeInterface? I can't just specify the interface directly as it's a class and not an enum.

I'm sure there is a specify syntactic sugar to make this work but I can't figure it out.

Example:

public class Main {
   public interface SomeInterface {
       public String doSomething();
   }

   public enum SomeEnum1 implements SomeInterface {
      something1;

      @Override
      public String doSomething() {
         return "SomeEnum1";
      }
   }

   public enum SomeEnum2 implements SomeInterface {
      something2;

      @Override
      public String doSomething() {
         return "SomeEnum2";
      }
   }

   public static void main(String[] args) {
      // Works but not polymorphic
      SomeEnum1 e1 = SomeEnum1.something1;
      System.out.println(e1.name() + " " + e1.doSomething());

      // Not an enum
      // SomeInterface e2 = SomeEnum1.something1;
      // System.out.println(e2.name() + " " + e2.doSomething());

      // Bounds mismatch
      // Enum<SomeInterface> e3 = SomeEnum1.something1;
      // System.out.println(e3.name() + " " + e3.doSomething());
   }
}

Upvotes: 2

Views: 96

Answers (4)

founderio
founderio

Reputation: 456

You cannot.
An enum type can, in Java, only have values defined for that enum type.

The closest thing to what you want you actually ansered yourself:

SomeInterface e2 = SomeEnum1.something1;

Edit: To be able to use the name() method, you will need to add it to the interface like so:

public interface SomeInterface {
    public String doSomething();
    public String name();
}

As that method is already available on any Enum, you don't have to re-implement it.

Are there specific reasons why you want that to be an enum? Using this approach here you get all the functionality defined in SomeInterface. I cannot imagine why you would need an enum here -> please elaborate if my answer is not close to what you need.

Upvotes: 1

fabian
fabian

Reputation: 82531

If you pass the value to a method, you can use generics to restrict the type of SomeInterface by 2 constraints:

public static void main(String[] args) {
    print(SomeEnum1.something1);
}

public static <T extends Enum & SomeInterface> void print(T t) {
    System.out.println(t.name() + " " + t.doSomething());
}

Upvotes: 2

Hoopje
Hoopje

Reputation: 12952

You can simple do:

SomeInterface e2 = SomeEnum1.something1;

The problem is that e2 is an interface, which can be implemented by any class, also classes which do not have a name() method. So if you want to access that method from SomeInterface-type references, you will have to include it in the interface:

interface SomeInterface {
    String name();
}

However, note that SomeInterface is still not an enum, so your can't switch on it, cannot use EnumSet and EnumMap, etc. Usually there are better solutions.

Upvotes: 0

Danail Alexiev
Danail Alexiev

Reputation: 7792

Instead of making the enum implement an interface, you can declare a static method and provide an implementation for each enum value.

public enum Animal {

    DOG {
        public void makeNoise() { System.out.println("Bark bark!"); }
    },

    CAT {
        public void makeNoise() { System.out.println("Prrrrr!"); }
    };

    public abstract void makeNoise();

}

That way you can use it like this:

Animal animal = Animal.DOG;
animal.makeNoise(); // prints "Bark bark!";

animal = Animal.CAT;
animal.makeNoise(); // prints "Prrrrr!"

Upvotes: 0

Related Questions