2012-08-10 14 views
7

ben gibi ortak bir arayüz uzatmak çeteleler koleksiyonu, bu yüzden bir şey var çalışılıyor:Enum <? uzanır arabirim>

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

ve sonra başka bir yerde değişken bir numaralandırma hem o uygulayarak bu faydalanmak ve arabirimi uygular. Yani çizgisinde bir şey ..

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

Ancak, bugüne kadar ben, yani arabirim uygulama olarak tedavi etmek amacıyla fe döküm zorunda

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

görünüyor ve bu olması gerekirken güvenli ... en küçük gibi görünüyor ve ben bir şeyle ilgileniyor olabilirim. Tabii ki paramizi bir Fooable olarak geçmeye çalışırsam, onu bir Enum olarak ele almak için döküm yaparım ve şimdi bu kazançsızlık artık güvenli bile değil. Aşağıdaki bakınız:

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

şey var mı ben alırsınız olarak 'iyi' çözüme yakın yaklaşık

Enum<? extends Fooable> 

bakan ya da tamam mı?

Java için nispeten yeni biriyim ve hala C veya C++ gibi kullanmaya çalışıyorum, bu yüzden bir testere yerine bir çekiç gibi davranıyorum ya da aptalca basit bir şeyle karşılaşmaktan çekinmeyin diye düşünüyorum :)

<T extends Enum<T> & Fooable> 

Böylece sizin yöntem olarak yazılabilir::

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

cevap

1

Bir seçenek ha

+0

Bunu düşünmüştüm, ama değerlerle ilgili davranışları hakkında rezervasyonlarım vardı(), şu anda tekrar gözden geçirilmeye değer olabilir, ancak şu anda geçerli bir rezervasyon için arama yapamam ... – Khanmots

+0

Bu gereksiz bir arayüz gerektirir . –

+0

@Mike, daha fazla düşünüyorum, bence doğru yol bu. Benim şartım gerçekten de ** tipinin ** bir enumm olması değil, bir enum'un ** davranışına * sahip olmasıdır. Ayrıca kendimi() şeyin bir sorun olmayacağını ve saçma olduğumu düşündüğüne kendimi ikna ettim. – Khanmots

18

Bu T Fooable Enum genişleten ve uygulayan demektir İstediğiniz Enum'dan Fooable'a herhangi bir yöntem eklemek veya Fooable'ı genişleten ve ihtiyacınız olan Enum yöntemlerini ekleyen yeni bir arayüz oluşturmaktır.

Örnek: Bunu yaptıktan sonra

interface Fooable { 
    void someCommonMethod(); 
} 

interface FooableEnum extends Fooable { 
    int ordinal(); 
} 

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

Eğer yöntem imzası parametre türü olarak FooableEnum kullanmak ve jenerik şeyler hiçbirini dert olamaz.

+0

Evet, ancak benim anlayışım, yalnızca bir yöntemi bir parametreye tanımlamayan bir jenerik ilan ederken kullanmak içindir? – Khanmots

+2

@Khanmots [Yöntemler genel olabilir] (http://docs.oracle.com/javase/tutorial/extra/generics/methods.html). –

+0

Bu yaklaşım düşünülmemişti ... bir T ile enine & Fooable genişletilmiş arayüzü ile deney yaptık, ancak tüm bu yöntemlerin tüm bu yüzden ekleyen sınıf jenerik yapma ile etrafında pusulamak zorunda olabilir Her iki sınırlama ile T ... – Khanmots