Why would an Enum implement an Interface?

前端 未结 16 2709
长发绾君心
长发绾君心 2020-11-28 01:34

I just found out that Java allows enums to implement an interface. What would be a good use case for that?

相关标签:
16条回答
  • 2020-11-28 01:50

    There is a case I often use. I have a IdUtil class with static methods to work with objects implementing a very simple Identifiable interface:

    public interface Identifiable<K> {
        K getId();
    }
    
    
    public abstract class IdUtil {
    
        public static <T extends Enum<T> & Identifiable<S>, S> T get(Class<T> type, S id) {
            for (T t : type.getEnumConstants()) {
                if (Util.equals(t.getId(), id)) {
                    return t;
                }
            }
            return null;
        }
    
        public static <T extends Enum<T> & Identifiable<S>, S extends Comparable<? super S>> List<T> getLower(T en) {
            List<T> list = new ArrayList<>();
            for (T t : en.getDeclaringClass().getEnumConstants()) {
                 if (t.getId().compareTo(en.getId()) < 0) {
                     list.add(t);
                }
            }
            return list;
        }
    }
    

    If I create an Identifiable enum:

        public enum MyEnum implements Identifiable<Integer> {
    
            FIRST(1), SECOND(2);
    
            private int id;
    
            private MyEnum(int id) {
                this.id = id;
            }
    
            public Integer getId() {
                return id;
            }
    
        }
    

    Then I can get it by its id this way:

    MyEnum e = IdUtil.get(MyEnum.class, 1);
    
    0 讨论(0)
  • 2020-11-28 01:51

    For example if you have a Logger enum. Then you should have the logger methods such as debug, info, warning and error in the interface. It makes your code loosely coupled.

    0 讨论(0)
  • 2020-11-28 01:52

    Since Enums can implement interfaces they can be used for strict enforcing of the singleton pattern. Trying to make a standard class a singleton allows...

    • for the possibility of using reflection techniques to expose private methods as public
    • for inheriting from your singleton and overriding your singleton's methods with something else

    Enums as singletons help to prevent these security issues. This might have been one of the contributing reasons to let Enums act as classes and implement interfaces. Just a guess.

    See https://stackoverflow.com/questions/427902/java-enum-singleton and Singleton class in java for more discussion.

    0 讨论(0)
  • 2020-11-28 01:53

    The Comparable example given by several people here is wrong, since Enum already implements that. You can't even override it.

    A better example is having an interface that defines, let's say, a data type. You can have an enum to implement the simple types, and have normal classes to implement complicated types:

    interface DataType {
      // methods here
    }
    
    enum SimpleDataType implements DataType {
      INTEGER, STRING;
    
      // implement methods
    }
    
    class IdentifierDataType implements DataType {
      // implement interface and maybe add more specific methods
    }
    
    0 讨论(0)
  • 2020-11-28 01:55

    Enums are just classes in disguise, so for the most part, anything you can do with a class you can do with an enum.

    I cannot think of a reason that an enum should not be able to implement an interface, at the same time I cannot think of a good reason for them to either.

    I would say once you start adding thing like interfaces, or method to an enum you should really consider making it a class instead. Of course I am sure there are valid cases for doing non-traditional enum things, and since the limit would be an artificial one, I am in favour of letting people do what they want there.

    0 讨论(0)
  • 2020-11-28 01:56

    I used an inner enum in an interface describing a strategy to keep instance control (each strategy is a Singleton) from there.

    public interface VectorizeStrategy {
    
        /**
         * Keep instance control from here.
         * 
         * Concrete classes constructors should be package private.
         */
        enum ConcreteStrategy implements VectorizeStrategy {
            DEFAULT (new VectorizeImpl());
    
            private final VectorizeStrategy INSTANCE;
    
            ConcreteStrategy(VectorizeStrategy concreteStrategy) {
                INSTANCE = concreteStrategy;
            }
    
            @Override
            public VectorImageGridIntersections processImage(MarvinImage img) {
                return INSTANCE.processImage(img);
            }
        }
    
        /**
         * Should perform edge Detection in order to have lines, that can be vectorized.
         * 
         * @param img An Image suitable for edge detection.
         * 
         * @return the VectorImageGridIntersections representing img's vectors 
         * intersections with the grids.
         */
        VectorImageGridIntersections processImage(MarvinImage img);
    }
    

    The fact that the enum implements the strategy is convenient to allow the enum class to act as proxy for its enclosed Instance. which also implements the interface.

    it's a sort of strategyEnumProxy :P the clent code looks like this:

    VectorizeStrategy.ConcreteStrategy.DEFAULT.processImage(img);
    

    If it didn't implement the interface it'd had been:

    VectorizeStrategy.ConcreteStrategy.DEFAULT.getInstance().processImage(img);
    
    0 讨论(0)
提交回复
热议问题