2012-04-02 20 views
9

Nếu tôi có:Có thể tạo các Bộ sưu tập Java an toàn kiểu mà các thành viên chỉ thực hiện một số giao diện không?

interface A{ void a(); } 
interface B{ void b(); } 

tôi có thể HAVA một phương pháp chung chung như thế này:

class C { 
    <T extends A & B> void c(T t) { 
     t.a(); 
     t.b(); 
    } 
} 

Nhưng tôi không thể HAVA một bộ sưu tập chung như thế này:

class D{ 
    List<? extends A & B> l; 
} 

tôi biết rằng tôi có thể tạo ra một giao diện trống E mở rộng cả A và B, và có một List chứa E's ... nhưng tôi muốn để lại các lớp được đánh dấu chỉ với A và B, và không cần phải có một E. T thậm chí còn có nhiều vấn đề hơn khi có nhiều A và B hơn có thể được kết hợp theo 2 cách.

Tôi thà có thể xác định một loại khi đang di chuyển, như là một liên kết các giao diện và có các bộ sưu tập nhận ra các đối tượng triển khai tất cả các giao diện như các thể hiện của loại đó.

Có cách nào để thực hiện điều này trong Java không? Tôi mở cửa cho bất kỳ loại công việc nào xung quanh hoặc hack vào thời điểm này để tránh tạo một giao diện mới và gắn thẻ các lớp học của tôi với nó, chỉ để họ có thể sống cùng nhau trong một bộ sưu tập. Hoặc, nếu ai đó có thể làm rõ cho tôi lý do tại sao điều này là không thể, điều đó sẽ được đánh giá cao như nhau.

+0

Ý bạn là và * giao lộ * của giao diện, phải không? – Saintali

+0

Tôi khá chắc chắn tôi có nghĩa là một liên minh của giao diện. Có lẽ bạn đang nghĩ về cách có một bộ khác nhau (hy vọng không phân tách) các lớp thực hiện mỗi giao diện. Sau đó, tập hợp các lớp thực hiện sự kết hợp của các giao diện là giao điểm của các bộ mô tả ở trên. –

Trả lời

9
public class Foo<T extends A & B> { 
    private List<T> list; 
    //getters, setters, etc. 
} 
+0

(Điều này bây giờ cho phép 'Foo l; 'trong' D'.) –

+1

tôi thấy rằng 'Foo ' có thể được công bố trong' D', nhưng không làm thế nào để nhanh chóng nó ... Tôi nên thêm rằng tôi sửa đổi câu hỏi để giải pháp nên được an toàn. Nếu không, điều này có thể được thực hiện với nguyên 'List's ngay từ đầu. –

0

Như Jeffrey cũng cho biết bằng cách nào đó, bạn phải parameterize lớp học của bạn D:

class D<T extends A & B> { 
    List<T> l; 

    /** 
    * this is just a method for the sake of example 
    */ 
    public T getSomeMember() { 
     return l.iterator().next(); 
    } 
} 

Bằng cách này bạn đang trì hoãn sự lựa chọn của bạn của các loại thực T với phương pháp đó thực sự insntatiates D. Nếu thông tin đó không phải là có sẵn ngay cả vào thời điểm đó bạn sẽ phải parameterize phương pháp mà quá với <T extends A & B>:

private <T extends A & B> 
void doSomething() { 
    D<T> d = new D<T>(); 

    T v1 = d.getSomeMember(); 
    A v2 = d.getSomeMember(); 
    B v3 = d.getSomeMember(); 
} 

Nếu có một lĩnh vực loại D trong một số lớp, sau đó lớp học mà phải biết loại thực tế rằng extends A & B hoặc được tham số hóa nếu không. Về nguyên tắc bạn truyền thông số kiểu lên cho đến khi bạn biết loại thực tế.

Được cảnh báo rằng quá trình này có khả năng trở thành không thể quản lý được đối với các mã lớn. Nó cũng có thể dẫn đến mã xấu, nhưng tất nhiên điều đó phụ thuộc vào quan niệm của bạn về tính thẩm mỹ.

+0

Toàn bộ vấn đề là tôi muốn tránh việc có một loại 'T' (đó sẽ là giao diện' E' từ câu hỏi ban đầu). Tôi muốn cho phép bất cứ thứ gì thực hiện cả 'A & B' vào bộ sưu tập và không có gì không thực hiện cả hai. Tôi không muốn yêu cầu các thành viên của bộ sưu tập có bất kỳ điểm chung nào ngoại trừ việc cả hai đều thực hiện 'A & B'. (Hoặc lý do này là không thể ...) –

Các vấn đề liên quan