2013-02-19 14 views
13

Znalazłem Enum s zdefiniowane jak poniżej:Enum metoda przesłanianie

public Enum MyEnum { 

    ONE 
    { 
     @Override 
     public int getSomething() { 
     return 1; 
     } 
    }, 

    TWO 
    { 
     @Override 
     public int getSomething() { 
     return 2; 
     } 
    } 

    int getSomething() 
    { 
     return 0; 
    } 
} 

Jakoś czuję pewnego rodzaju dyskomfort z tego wdrożenia, ponieważ myślę, że idealnie pola powinny zostać zdefiniowane w tym celu, a klasa powinna wyglądać mniej więcej:

Problem polega na tym, że oprócz osobistego dyskomfortu nie mogę znaleźć żadnego dobrego powodu, aby zmienić ten kod. Czy istnieje?

+1

Drugi formularz sprawia, że ​​jest bardziej czytelny i bardziej rozszerzalny, przejdź do tego! –

+0

Jest to * maszyna stanu * w pierwszym przykładzie. Nie zaimplementowane całkiem poprawnie ('getSomething()' powinno być abstrakcyjne) ... ale właśnie dlatego używasz tego typu struktury. Metody są na ogół dużo bardziej złożone w rzeczywistym przykładzie (faktycznie wykonują operacje, a nie zwracają wartości statyczne) i/lub rzucają 'IllegalStateException', gdy nie powinny być wywoływane w bieżącym stanie. –

+1

Obie te metody są prawidłowe. –

Odpowiedz

18

(przeniesiony z komentarzem)

Pierwszym przykładem jest używany powszechnie do wdrożenia automat skończony w Javie. Eliminuje to konieczność dla każdej metody mające mieć if (state == FOO) {} else if (state == BAR) itp

class MyFSM { 

    enum State { 
     FIRST_STATE { 
      @Override 
      void start(MyFSM fsm) { 
       fsm.doStart(); 
      } 
      @Override 
      void stop(MyFSM fsm) { 
       throw new IllegalStateException("Not Started!"); 
      } 
     }, 
     SECOND_STATE { 
      @Override 
      void start(MyFSM fsm) { 
       throw new IllegalStateException("Already Started!"); 
      } 
      @Override 
      void stop(MyFSM fsm) { 
       fsm.doStop(); 
      } 
     }; 

     abstract void start(MyFSM fsm); 
     abstract void stop(MyFSM fsm);  
    } 

    private volatile State state = State.FIRST_STATE; 

    public synchronized void start() { 
     state.start(this); 
    } 

    private void doStart() { 
     state = SECOND_STATE; 
    } 

    public synchronized void stop() { 
     state.stop(this); 
    } 

    private void doStop() { 
     state = FIRST_STATE; 
    } 
} 
+0

Sprawa wykorzystuje proste metody wyliczania, po prostu getter. Ale dobrze to wiedzieć, dzięki! – Sednus

+0

To jest przesada, IMHO. Ważne ... ale przesada. Powyższe jest jedynym powodem, dla którego go użyłbym. –

0

Pierwszy wzór jest nieco lepsza dla metody „Default”, że nie wszyscy muszą być zastąpione nowymi.

public enum Modes { 
    MODE_ONE { 
     @Override public boolean canDoA() { 
      return true; 
     } 
    }, 
    MODE_TWO { 
     @Override public boolean canDoB() { 
      return true; 
     } 
    }, 
    MODE_THREE { 
     @Override public boolean canDoC() { 
      return true; 
     } 
    }; 

    public boolean canDoA() { 
     return false; 
    } 

    public boolean canDoB() { 
     return false; 
    } 

    public boolean canDoC() { 
     return false; 
    } 

}