Java Enums:声明后实现方法?

时间:2012-04-02 20:20:49

标签: java

考虑下面在Enum中实现方法的简单示例。这种方法的一个问题是,当你有很多枚举实例时,你在视觉上不能再一次看到它们作为一个列表。也就是说,如果我们有很多玩具,我想在一个长列表中看到“DOLL,SOLDIER,TEDDYBEAR,TRAIN,ETC”,然后在那个列表之后我可以实现任何所需的方法,例如枚举本身是抽象的方法。

有没有办法做到这一点?或者,在声明单个枚举实例时是否必须实现这些方法,如下例所示?

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();
}

3 个答案:

答案 0 :(得分:6)

想到的一种方法是将抽象方法的实现留给单独的实现类,例如:

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."); 
    }
}

如果您的实现具有足够的复杂性以保证分离,此设置将允许您在单独的文件中创建行为类。

如果实现很简单,可以将它包含在一个enum类中,那么可以将接口和行为类作为枚举类的子类:

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 ...
}

我可能会选择自己的第一个实现,除非实现类的层次结构非常简单。

答案 1 :(得分:4)

如果你想要更紧凑的枚举声明,我能想到的唯一方法是:

如果你可以用初始化变量构造你的方法:

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

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

或稍微复杂一点的功能,如果行为更复杂 -

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();}
 }

答案 2 :(得分:2)

您可以尝试以下方式:

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;
        }
    }
}

不是很漂亮,但它会将你的枚举声明放在一起。