2012-08-10 4 views
7

Ja próbuje mieć kolekcję teksty stałe, które rozciągają się wspólny interfejs, więc coś takiego:Enum <? rozszerza interfejs>

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

a następnie skorzystać z tego gdzie indziej poprzez egzekwowanie zarówno, że zmienna jest Enum i implementuje interfejs. Więc coś wzdłuż linii ..

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

Jednak do tej pory wydaje się, że aby rzucić fe, aby traktować go jako wdrożenie interfejsu, czyli

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

a jednocześnie powinny być bezpieczny ... wydaje się nieoptymalny i mogę coś przeoczyć. Oczywiście, jeśli spróbuję po prostu przekazać ten paramat jako Fooable, wtedy rzucam casting, by traktować to jako Enum i nie tylko to jest to, że nie jestem jeszcze bezpieczny, nie jestem nawet bezpieczny. Zobacz co następuje:

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

Czy coś mi wychodzi lub jest

Enum<? extends Fooable> 

o tak blisko rozwiązania „dobry” jak będę miał?

Jestem względnie nowy w Javie i nadal łapię się na tym, że próbuję go użyć jak C lub C++, więc jeśli traktuję to jak młotek zamiast piły lub coś przeoczę głupio prosto, proszę o wskazanie go :)

Odpowiedz

1

jedna opcja ty ha ve jest dodanie dowolnej metody z Enum, czego potrzebujesz, na Fooable lub utworzenie nowego interfejsu, który rozszerza Fooable i dodaje potrzebne metody Enum.

Przykład:

interface Fooable { 
    void someCommonMethod(); 
} 

interface FooableEnum extends Fooable { 
    int ordinal(); 
} 

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

Po wykonaniu tego można użyć FooableEnum jako typ parametru w podpisie metoda i nie martwić się o każdy generycznego rzeczy.

+0

Zastanowiłem się nad tym, ale miałem zastrzeżenia co do tego zachowania w odniesieniu do wartości(), może warto jednak wrócić, ponieważ teraz nie jestem w stanie wyodrębnić ważnej rezerwacji ... – Khanmots

+0

Wymaga to niepotrzebnego interfejsu . –

+0

@Mike, więcej Myślę, że tym bardziej uważam, że to właściwa ścieżka. Moim wymaganiem nie jest to, że typ ** jest ** enumm, to że ma ** zachowanie ** wyliczenia. Przekonałam się też, że rzeczy value() nie będą stanowić problemu i że jestem głupi. – Khanmots

18

oznacza to, że T rozciąga Enum i wdraża Fooable:

<T extends Enum<T> & Fooable> 

Zatem metoda może być zapisany jako:

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

tak, ale moim zdaniem jest to tylko do użytku, gdy deklaruje ogólne, nie definiujące parametru do metody? – Khanmots

+2

@Khanmots [Metody same w sobie mogą być ogólne] (http://docs.oracle.com/javase/tutorial/extra/generics/methods.html). –

+0

Nie myślałem o tym podejściu ... eksperymentowałem z interfejsem generycznym z T rozszerzającym Enum & Fooable , ale może musiałem pójść dookoła z tworzeniem generycznej klasy otaczającej, aby wszystkie jej metody mogły mieć T z oboma ograniczeniami ... – Khanmots