2012-04-02 60 views
9

如果我有:是否有可能創建類型安全的Java集合,其成員僅僅實現多個接口?

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

我可以哈瓦這樣的通用方法:

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

但我不能哈瓦泛型集合是這樣的:

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

我知道我可以創建一個空的接口E,它擴展了A和B,並且有一個包含E的List ...但我寧願讓我的類只用A和B標記,而不必具有E.T當有更多的A和B可以以2^n種方式組合時,他的問題更加棘手。

我寧願能夠實時定義一個類型,作爲接口的聯合,並使集合能夠識別將所有接口實現爲該類型實例的對象。

有沒有辦法在Java中做到這一點?爲了避免創建新的界面,併爲我的類添加標籤,以便他們可以共同生活在一個集合中,我願意接受任何類型的工作或者入侵。或者,如果有人能夠向我澄清爲什麼這是不可能的,那將會同樣感激。

+0

你的意思是和交叉*的接口,不是嗎? – Saintali 2012-04-03 06:43:05

+0

我很確定我的意思是接口的聯合。您可能正在考慮如何實現每個接口的不同類(希望不是分離的)。然後,實現接口聯合的類集合就是上述集合的交集。 – 2012-04-03 21:59:07

回答

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

(現在允許'Foo l;'在'D'中。) – 2012-04-02 00:27:59

+1

我看到'Foo '可以在'D'中聲明,但不是如何實例化它......我應該補充說我修改了這個問題所以解決方案應該是安全的。否則,這可以從一開始就用原始的'List'完成。 – 2012-04-02 03:19:05

0

正如傑弗裏還莫名其妙地說,你有你的參數類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(); 
    } 
} 

這種方式,您都推遲您的實際類型T的選擇,這實際上insntatiates D的方法。如果該信息,即使在這一點上是不可用,你將不得不參數這種方法也有<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(); 
} 

如果在某些類D類型的字段,則這個類必須知道實際的類型extends A & B或者如果它沒有參數化的話。原則上,您將傳播類型參數直到您知道實際類型。

被警告,這個過程很可能變得難以管理的大碼。它也可能導致難看的代碼,但當然這取決於你的美學概念。

+0

整個問題是我想避免使用'T'類型(它將成爲原始問題的接口'E')。我想允許在集合中實現'A&B'的任何事物,而不是兩者都不實現。我不想要求集合的成員有任何共同之處,只是它們都實現了'A&B'。 (或者這是不可能的原因...) – 2012-04-03 22:06:10

相關問題