2013-02-19 14 views
13

ho trovato Enum s definiti come la seguente:metodo Enum l'override

public Enum MyEnum { 

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

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

    int getSomething() 
    { 
     return 0; 
    } 
} 

In qualche modo mi sento un certo tipo di disagio con questa implementazione perché vorrei pensare che idealmente un campo deve essere definito per questo scopo e la classe dovrebbe essere simile:

public Enum MyEnum{ 

    ONE(1), 
    TWO(2) 

    private int theSomething; 

    private MyEnum(int something) { 
     theSomething = something; 
    } 

    int getSomething() 
    { 
     return theSomething; 
    } 
} 

Il problema è che, a parte il disagio personale, non riesco a trovare una buona ragione per cambiare questo codice. Esiste?

+1

Il secondo modulo lo rende più leggibile e più estensibile, scegli quello! –

+0

È una * macchina a stati * nel tuo primo esempio. Non implementato correttamente ('getSomething()' dovrebbe essere astratto) ... ma è per questo che usi quel tipo di struttura. E i metodi sono generalmente molto più complessi in un esempio reale (in realtà fanno cose piuttosto che restituire valori statici) e/o lanciano 'IllegalStateException' quando non dovrebbero essere chiamati in uno stato corrente. –

+1

Entrambi sono approcci validi. –

risposta

18

(spostato da commentare)

Il primo esempio è usato comunemente per implementare una macchina a stati finiti in Java. Si elimina la necessità di ogni metodo di dover avere un if (state == FOO) {} else if (state == BAR) ecc

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

Il caso usa un enum semplice, solo metodi getter. Ma bello saperlo, grazie! – Sednus

+0

Quindi è eccessivo, IMHO. Valido ... ma eccessivo. Quanto sopra è l'unica ragione per usarlo. –

0

Il primo modello è leggermente migliore per i metodi di "default" che non tutti hanno bisogno di essere sovrascritto.

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

}