Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extending Java Enums

Tags:

java

enums

I have a question regarding the best design pattern for code reuse when dealing with Java enums. Basically, what I'm trying to achieve is being able to define several enums that model static business collections (sets of constants), but I'd also like to share behavior between them, with minimal coding.

This is trivial to achieve with class inheritance from abstract classes but, since Java enums cannot be extended (they can only implement interfaces), this type of work is tedious and involves a lot of error prone copy/paste work (copying the code from enum to enum). Examples of "business logic" that should be shared among all enums includes converting from/to Strings, instance and logical comparison, etc.

My best shot right now is using helper classes in conjunction with business interfaces, but this only goes so far in reducing code complexity (as all enums still have to declare and invoke the helper classes). See example (just to clarify):

public enum MyEnum {
    A, B, C;

    // Just about any method fits the description - equals() is a mere example
    public boolean equals(MyEnum that) {
        ObjectUtils.equals(this, that);
    }
} 

How do StackOverflowers deal with this "language feature"?

like image 807
lsoliveira Avatar asked Jan 10 '12 16:01

lsoliveira


People also ask

Can you extend a Java enum?

No, we cannot extend an enum in Java. Java enums can extend java. lang. Enum class implicitly, so enum types cannot extend another class.

Can enums extend each other?

Enum and has several static members. Therefore enum cannot extend any other class or enum: there is no multiple inheritance. Class cannot extend enum as well. This limitation is enforced by compiler.

Can enum be inherited?

Inheritance Is Not Allowed for Enums.

Can we override enum in Java?

Enums are exactly final inner classes that extends java. lang. Enum<E> . You cannot extend, override or inherit an enum .


1 Answers

You can move the reusable logic to dedicated (non-enum) classes and then have the enums delegate to those classes. Here's an example:

[Side note: the inheritance of PlusTwo extends PlusOne is not recommended (b/c PlusTwo is not PlusOne). It here just to illustrate the point of being able to extend an existing logic.]

public interface Logic {
  public int calc(int n);
}

public static class PlusOne implements Logic {
  public int calc(int n) { return n + 1; }
}

public static class PlusTwo extends PlusOne {
  @Override
  public int calc(int n) { return super.calc(n) + 1; }
}

public static enum X {
  X1, X2;   
  public Logic logic;

  public int doSomething() { 
    return logic.calc(10);
  }
}

public static enum Y {
  Y1, Y2;
  public Logic logic;

  public String doSomethingElse() { 
    return "Your result is '" + logic.calc(10) + "'";
  }
}

public static void main(String[] args) {
  // One time setup of your logic:
  X.X1.logic = new PlusOne();
  X.X2.logic = new PlusTwo();  
  Y.Y1.logic = new PlusOne();
  Y.Y2.logic = new PlusTwo();

  System.out.println(X.X1.doSomething());
  System.out.println(X.X2.doSomething());
  System.out.println(Y.Y1.doSomethingElse());
  System.out.println(Y.Y2.doSomethingElse());
}
like image 128
Itay Maman Avatar answered Sep 28 '22 16:09

Itay Maman