How to add common methods for a few Java enums? (abstract class ancestor?)

后端 未结 5 662
孤街浪徒
孤街浪徒 2021-01-04 07:01

I have a few Java enums as such

public enum Aggregation
{
    MORTGAGE( \"Mortgage\" ),
    POOLS( \"Pools\" ),
    PORTFOLIO( \"Portfolio\" );

    private         


        
相关标签:
5条回答
  • 2021-01-04 07:22

    Favor composition over inheritance and programming for the sake of interfaces. Since Enums are classes (not regular, but still - classes) you can create some field containing shared logic, let the enum implement you interface and delegate implementation to this field.

    Relevant code snippets:

    Shared interface

    public interface MyInterface {
    
        void someMethod();
    
    }
    

    Logic implementation

    public class MyInterfaceImpl implements MyInterface {
    
        public void someMethod() {
            System.out.println("Do smth...");
        }
    
    }
    

    First enum

    public enum EnumA implements MyInterface {
        ;
    
        private MyInterface impl = new MyInterfaceImpl();
    
        public void someMethod() {
            impl.someMethod();
        }
    
    }
    

    Second enum

    public enum EnumB implements MyInterface {
        ;
    
        private MyInterface impl = new MyInterfaceImpl();
    
        public void someMethod() {
            impl.someMethod();
        }
    
    }
    

    Please do note that EnumA and EnumB are not really code duplication, since that is plain delegation (valid, in my opinion). Also please note that everything is nicely glued together by using interface.

    0 讨论(0)
  • 2021-01-04 07:23

    How about a static helper class that holds your common functions, call them from your enum methods.

    In regards to your comment about toString().

    public enum MyEnum{
    
    ONE("one");
    
    public MyEnum(String m_Name){
      this.m_Name = m_Name;
    }
    public String toString(){
      return m_Name;
    }
    String m_Name;
    }
    
    0 讨论(0)
  • 2021-01-04 07:24

    just define your common behviur in the First class:

    public class First {
     public String name() {
      return "my name";
     }
     ...
    }
    

    and than extend it in each class:

    public SecondClass extends First {
     ...
    }
    
    0 讨论(0)
  • 2021-01-04 07:31

    Here is how you can solve your problem with composition and delegation. (I think this is the DRYest you can get with Java, for the case in hand.)

    import java.util.*;
    
    interface HasName {
      public String getName();
    }
    
    class EnumEnhancer<E extends Enum<E> & HasName> {
      private Map<String, E> lookup;
    
      public EnumEnhancer(E... values) {
        lookup = new HashMap<String, E>();
        for (E e : values) {
          lookup.put(e.getName(), e);
        }
      }
    
      public E lookup(String name) {
        return lookup.get(name);
      }
    
      public String toString(E e) {
        return e.getName();
      }
    }
    
    enum Color implements HasName { // This is interface inheritance.
      RED("red"), GREEN("green"), BLUE("blue");
    
      // This is composition. 
      private static final EnumEnhancer<Color> enhancer = 
        new EnumEnhancer<Color>(values());
    
      private String name;
    
      private Color(String name) {
        this.name = name;
      }
    
      public String getName() {
        return name;
      }
    
      // This is delegation.
      public String toString() {
        return enhancer.toString(this);
      }
    
      // This too is delegation.     
      public static Color lookup(String name) {
        return enhancer.lookup(name);
      }
    }
    
    class Main {
      public static void main(String[] args) {
        System.out.println(Color.lookup("blue")); // prints blue
      }
    }
    
    0 讨论(0)
  • 2021-01-04 07:33

    You can achieve this with Java 8 default interface methods:

    public class test
    {
        public static void main (String[] arguments) throws Exception
        {
            X.A.foo ();
            Y.B.foo ();
        }
    }
    
    interface MyEnumInterface
    {
        String getCommonMessage ();
        String name ();
    
        default void foo ()
        {
            System.out.println (getCommonMessage () + ", named " + name ());
        }
    }
    
    enum X implements MyEnumInterface
    {
        A, B;
    
        @Override
        public String getCommonMessage ()
        {
            return "I'm an X";
        }
    }
    
    enum Y implements MyEnumInterface
    {
        A, B;
    
        @Override
        public String getCommonMessage ()
        {
            return "I'm an Y";
        }
    }
    

    Note that the interface doesn't know it will be implemented by enums, so it cannot use Enum methods on this in the default methods. However, you may include those methods in the interface itself (like I did with name()) and then use them normally. They will be "implemented" for you by Enum when you declare an enumeration.

    0 讨论(0)
提交回复
热议问题