2012-08-10 18 views
7

Tôi đang cố gắng để có một bộ sưu tập của enums rằng mở rộng một giao diện chung, vì vậy cái gì đó như:Enum <? mở rộng giao diện>

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

và sau đó tận dụng điều này ở nơi khác bằng cách thực thi cả hai mà một biến là một Enum triển khai giao diện. Vì vậy, một cái gì đó dọc theo dòng của ..

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

Tuy nhiên, cho đến nay tôi dường như phải bỏ fe để đối xử với nó như thực hiện giao diện, tức là,

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

và trong khi điều này nên an toàn ... có vẻ như tối ưu và tôi có thể nhìn cái gì đó. Tất nhiên nếu tôi cố gắng vượt qua tham số như một Fooable thì tôi sẽ cố gắng để đối xử với nó như là một Enum và không chỉ là sự không đạt được này mà bây giờ tôi thậm chí còn không an toàn. Xem sau:

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

Có điều gì tôi đang nhìn hay là

Enum<? extends Fooable> 

về càng gần đến một giải pháp 'tốt' như tôi sẽ nhận được?

Tôi tương đối mới với Java và vẫn bắt mình cố gắng sử dụng nó như C hoặc C++ vì vậy nếu tôi xử lý nó như một cái búa thay vì cưa hoặc nhìn một cái gì đó ngu ngốc đơn giản cảm thấy tự do để chỉ nó ra :)

Trả lời

1

Một lựa chọn bạn ha ve là thêm bất kỳ phương thức nào từ Enum bạn cần vào Fooable hoặc tạo một giao diện mới mở rộng Fooable và thêm các phương thức Enum mà bạn cần.

Ví dụ:

interface Fooable { 
    void someCommonMethod(); 
} 

interface FooableEnum extends Fooable { 
    int ordinal(); 
} 

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

Một khi bạn đã làm điều này bạn có thể sử dụng FooableEnum như các loại tham số trong phương pháp chữ ký của bạn và không phải lo lắng về bất cứ những thứ chung chung.

+0

Tôi đã nghĩ về điều này, nhưng tôi đã đặt trước về hành vi của nó đối với các giá trị(), có thể đáng xem xét lại mặc dù hiện tại tôi không thể nạo vét một đặt phòng hợp lệ ... – Khanmots

+0

Điều này đòi hỏi một giao diện không cần thiết . –

+0

@Mike, tôi càng nghĩ về điều này thì tôi càng nghĩ đó là con đường chính xác. Yêu cầu của tôi không thực sự là kiểu ** là ** enumm, nó có ** hành vi ** của một enum. Tôi cũng đã thuyết phục bản thân rằng các giá trị() không phải là một vấn đề và tôi là ngớ ngẩn. – Khanmots

18

Điều này có nghĩa rằng T kéo dài Enum và thực hiện Fooable:

<T extends Enum<T> & Fooable> 

vì vậy phương pháp của bạn có thể được viết như sau:

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

vâng, nhưng sự hiểu biết của tôi là chỉ sử dụng khi khai báo một generic không xác định tham số cho một phương thức? – Khanmots

+2

@Khanmots [Phương thức có thể là chung chung] (http://docs.oracle.com/javase/tutorial/extra/generics/methods.html). –

+0

Đã không nghĩ đến cách tiếp cận đó ... đã thử nghiệm với giao diện chung với T mở rộng Enum & Fooable , nhưng có thể phải đi xung quanh với việc tạo ra lớp chung chung để tất cả các phương thức của nó có thể có T với cả hai ràng buộc ... – Khanmots