Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Enums: Implementing methods After Declaration?

Tags:

java

Consider the simple example below of implementing a method in an Enum. One problem with this method is that, when you have a lot of enum instances, you visually can no longer see them all at once, as a list. That is, if we had many toys, I would like to see "DOLL, SOLDIER, TEDDYBEAR, TRAIN, ETC", together, in one long list, and then after that list I could implement any needed methods, e.g. methods that are abstract in the enum itself.

Is there any way to do this? Or do you have to implement the methods when you declare the individual enum instances, as in the example below?

public enum Toy {
     DOLL() {
          @Override public void execute() { 
               System.out.println("I'm a doll."); 
          }
     },
     SOLDIER() {
          @Override public void execute() { 
               System.out.println("I'm a soldier."); 
          }
     };
     //abstract method
     public abstract void execute();
}
like image 920
Jonah Avatar asked Apr 02 '12 20:04

Jonah


3 Answers

One way that comes to mind is to leave the implementation of the abstract methods to separate implementation classes, something like:

interface ToyBehaviour {

    void execute();
}

public enum Toy {
     DOLL(new DollBehaviour()),
     SOLDIER(new SoldierBehaviour());

     private final ToyBehaviour behaviour;    

     Toy(ToyBehaviour impl) {

        behaviour = impl;
     }

     public void execute() {

        behaviour.execute();
     }
}

class DollBehaviour implements ToyBehaviour {

    public void execute() { 
        System.out.println("I'm a doll."); 
    }
}

This setup would allow you to create behaviour classes in separate files in the case that your implementation has enough complexity to warrant separation.

In the case that the implementation is simple enough to include it into the one enum class, you can put the interface and behaviour classes as children of the enum class:

public enum Toy {
     // enum values
     DOLL(new DollBehaviour()),
     SOLDIER(new SoldierBehaviour());

     private final ToyBehaviour behaviour;    

     Toy(ToyBehaviour impl) {

        behaviour = impl;
     }

     public void execute() {

        behaviour.execute();
     }

    // behaviour interface
    interface ToyBehaviour {

        void execute();
    }

    // behaviour implementation (sub)classes
    static class DollBehaviour implements ToyBehaviour {

        public void execute() { 
            System.out.println("I'm a doll."); 
        }
    }

    // etc ...
}

I would probably opt for the first implementation myself, unless the hierarchy of implementation classes is very trivial.

like image 91
rsp Avatar answered Nov 15 '22 14:11

rsp


If you want more compact enum declarations, the only ways I can think of to do it are :

if you can construct your methods out of initializer variables:

public enum Toy {
     DOLL("doll"),SOLDIER("soldier");

     private Toy(String name){ this.name=name;}
     public void execute(){ System.out.println("I'm a "+name );}
 }

or, slightly more complicated, kind of the same with functions, if the behavior is more complex -

abstract class SomeToyMethod {
  abstract void execute();

  public SomeToyMethod DOLL_METHOD = new SomeToyMethod(){ 
     public void execute(){  System.out.println("I'm a doll");})
  public SomeToyMethod SOLDIER_METHOD = new SomeToyMethod(){ 
     public void execute(){  System.out.println("I'm a soldier");})


public enum Toy {
     DOLL(SomeToyMethod,DOLL_METHOD),SOLDIER(SomeToyMethod.SOLDIER_METHOD);

     private Toy(SomeToyMethod method){ this.method=method;}
     public void execute(){ method.execute();}
 }
like image 43
Steve B. Avatar answered Nov 15 '22 16:11

Steve B.


You could try something like:

public enum Toy {
    DOLL,
    SOLDIER,
    ANOTHER_TOY;

    public static void execute(Toy toy) {
        switch(toy) {
            case DOLL:
                System.out.println("I'm a doll."); 
                break;
            case SOLDIER:
                System.out.println("I'm a soldier."); 
                break;
            case ANOTHER_TOY:
                System.out.println("I'm another toy."); 
                break;
        }
    }
}

Not very pretty but it keeps your enum declarations together.

like image 2
darrengorman Avatar answered Nov 15 '22 16:11

darrengorman