2012-08-10 16 views
7

sto cercando di avere una collezione di enumerazioni che si estendono un'interfaccia comune, in modo da qualcosa come:Enum <? estende l'interfaccia>

interface Fooable 
{ 
    void someCommonMethod(); 
} 

enum E1 implements Fooable 
{ 
    // some enumuerations and a definition for someCommonMethod() 
} 

enum E2 implements Fooable 
{ 
    // some different enumerations and a different definition for someCommonMethod() 
} 

e poi fare uso di questo altrove applicando sia che una variabile è un Enum e implementa l'interfaccia. Quindi, qualcosa sulla falsariga di ..

bar(Enum<? extends Fooable> fe) 
{ 
    fe.ordinal(); 
    fe.someCommonMethod(); 
} 

Tuttavia, finora mi sembra di avere a gettare fe al fine di trattare come implementando l'interfaccia, vale a dire,

bar(Enum<? extends Fooable> fe) 
{ 
    fe.ordinal(); 
    ((Fooable)fe).someCommonMethod(); 
} 

e mentre questo dovrebbe essere sicuro ... sembra non ottimale e potrei trascurare qualcosa. Certo che se provo a passare il param come Fooable, finisco col cast per considerarlo un Enum e non solo questo non guadagno non sono nemmeno sicuro. Vedere seguente:

bar(Fooable fe) 
{ 
    // potentially unsafe cast! 
    ((Enum<?>)fe).ordinal(); 
    fe.someCommonMethod(); 
} 

C'è qualcosa che sto affaccia o è il

Enum<? extends Fooable> 

quanto di più vicino ad una soluzione 'buona', come vado a prendere?

Sono relativamente nuovo a Java e sto ancora cercando di usarlo come C o C++ quindi se lo sto trattando come un martello invece di una sega o trascurando qualcosa di stupidamente semplice sentiti libero di indicarlo :)

risposta

1

una possibilità che si ha È necessario aggiungere uno qualsiasi dei metodi di Enum di cui si ha bisogno su Fooable o creare una nuova interfaccia che estenda Fooable e aggiunga i metodi Enum necessari.

Esempio:

interface Fooable { 
    void someCommonMethod(); 
} 

interface FooableEnum extends Fooable { 
    int ordinal(); 
} 

enum E1 implements FooableEnum { 
    // Implement someCommonMethod. 
    // ordinal() is already implemented by default. 
} 

Una volta fatto questo è possibile utilizzare FooableEnum come il tipo di parametro nella vostra firma del metodo e non preoccuparsi di una qualsiasi delle cose generiche.

+0

Avevo pensato a questo, ma ho avuto riserve circa il suo comportamento rispetto ai valori(), può valere la pena di rivisitare anche se, come in questo momento io non sono in grado di dragare una prenotazione valida ... – Khanmots

+0

Questo richiede un'interfaccia inutile . –

+0

@Mike, più ci penso e più penso che sia la strada giusta. Il mio requisito non è che il tipo ** sia ** un enumma, è che ha il ** comportamento ** di un enum. Mi sono anche convinto che la value() cosa non sarà un problema e che sono stato sciocco. – Khanmots

18

Ciò significa che T si estende Enum e implementa Fooable:

<T extends Enum<T> & Fooable> 

così il metodo può essere scritta come:

<T extends Enum<T> & Fooable> void bar(T fe) { 
    fe.ordinal(); 
    fe.someCommonMethod(); 
} 
+0

sì, ma la mia comprensione è che è solo per l'uso quando si dichiara un generico che non definisce un parametro per un metodo? – Khanmots

+2

@ Khanmots [I metodi stessi possono essere generici] (http://docs.oracle.com/javase/tutorial/extra/generics/methods.html). –

+0

Non avevo pensato a quell'approccio ... avevo sperimentato con l'interfaccia generica con una T estesa Enum e Fooable , ma potrebbe dover andare in giro con la classe di inclusione generica in modo che tutti i suoi metodi possano avere un T con entrambi i vincoli ... – Khanmots

Problemi correlati