2009-01-13 62 views
3

基本上我想這樣做:你可以同時要求多種類型嗎?

public interface A { 
    void a(); 
} 
public interface B { 
    void b(); 
} 
public class SomeClass { 
    public SomeClass(<A&B> e) { // Note the type here 
     e.a(); 
     e.b(); 
    } 
} 

我所做的註釋行顯然是違法的。我知道我可以只需要傳遞的對象來實現接口A或接口B,但是有兩種方法可以實現這兩種接口嗎?

我想有一些解決方法(比如要求參數是A類型,然後檢查它是否也是B的一個實例),但這樣我就不能從編譯器獲得幫助。你知道有什麼辦法可以做到嗎?或者,也許更聰明的解決方法...

回答

16

你可以使用泛型啓用。例如,要接受一些類,同時實現了CharSequence的和可附加的一個實例:

public <T extends CharSequence & Appendable> void someMethod(T param) { 
    ... 
    } 
+2

這感覺很混亂,因爲你仍然需要定義一個實現A和B的類型T.爲什麼不只是讓參數類型?如果許多對象實現A和B,爲什麼不製作一個接口C:A,B? – 2009-01-13 14:00:54

3

根據不同的設計,您可以執行下列操作之一:

  1. 讓A:B或B:答:
  2. 將界面C:A,b。

無論哪種方式,你會希望有合同既包括()和b()。

+0

謝謝,但繼承選項並不總是有意義的(A和B可能是完全不相關的,我也不太喜歡第二個選項,因爲這意味着1)我可能必須爲每個接口創建'C接口'可能的接口組合和2)類應該都實現這些... – Jordi 2009-01-13 08:13:43

+0

就像我說的,它取決於設計。如果A和B有關,那麼1)會起作用。 2)雖然真的很不好。一個anb B有些相關,因爲你傳入了一個實現兩者的對象。那麼實現兩者的基類呢? – 2009-01-13 13:59:32

1

在黑暗中拍攝只是,我不知道這是否是正確的語法,也就是說,如果你要重新聲明這個C中的方法,但是什麼:

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

public interface C extends A, B{} 

public class SomeClass{ 
    public SomeClass(C e) { // Note the type here 
     e.a(); 
     e.b(); 
    } 

} 
3

嗯,還有就是<T extends A & B> f(T ab)記譜法,但你應該贊成合成而不是繼承。你並不需要擴展任何東西。只是做一個類型,它是兩種類型的AB聯合工會(產品),具體如下:

public abstract class P2<A, B> { 
    public A _1(); 
    public B _2(); 
} 

有時也稱爲產品-2,或「對」型。您可以爲這些創造一個方便的構造函數:

public final class P { 
    private P() {} 
    public static <A, B> P2 p(final A a, final B b) { 
    return new P2<A, B>() { 
     public A _1() { 
     return a; 
     } 
     public B _2() { 
     return b; 
     } 
    } 
    } 
} 

注意,您可以使用相同的對象爲兩個參數,如果AB是接口和你的對象實現兩者:

P2<A, B> both = P.p(o, o); 

或者你可以自由地使用兩個不同的對象,使設計更加美觀和分離。

您將在Functional Java庫中找到此類型以及多達8種類型的產品。還有一種稱爲Either<A, B>的類型,即不相交聯合(總和)兩種類型,從而它保留的值爲AB(或兩者)。

0

如果你有一個方法需要兩個不同的接口作爲參數,只需要讓它有兩個參數。

public void foo(A a, B b) { 
    .... 
} 

這並不難,相信我。

相關問題