2013-07-05 171 views
11

此代碼完美工作。 test()方法適用於這兩個接口。發動機罩下面究竟發生了什麼?這個功能在實際場景中如何有用?實現多個具有相同方法的接口

interface A 
{ 
    void test(); 
} 

interface B 
{ 
    void test(); 
} 

class C implements A, B 
{ 

    public void test() 
    { 
     System.out.println("abc"); 
    } 
} 

    A a = new C(); 
    a.test(); 
    B b = new C(); 
    b.test(); 
+0

[Java抽象類實現接口的可能重複,都有相同的方法](http://stackoverflow.com/questions/15202185/java-abstract-class-implements-an-interface-both-have-the -same-method) –

+0

請不要重複關於抽象類和接口,它與兩個接口基本相同。 –

+0

可能的重複[在一個類中實現2個接口,方法相同。哪個接口方法被覆蓋?](http://stackoverflow.com/questions/2801878/implemeting-2-interfaces-in-a-class-with-same -method-which-interface-method-is-o) – adatapost

回答

12

因爲它的接口也沒有做過傷害。通過實施AB,您基本上正在爲您的C課程使用藍圖。無論ABC應實施一個名爲test()

C類的方法實現了該方法,所以接口都做他們的工作。

它基本上是你的C類說:「哦,嘿,我需要執行test()因爲接口A」,你實現它。然後你的C類說:「哦,嘿,我需要再次實施test(),因爲接口B」,它看到已經有一種方法稱爲test()實現,因此它滿意。

你也可以在這裏找到更多的信息:JLS §8.4.8.4

1

不就語法而言,但如果methods之一的intent不遵守,其合同被打破,代碼可以被視爲打破

用你的比喻,如果我答應Michael穿藍色襯衫而不是紅色襯衫,而且我不能穿兩件襯衫,那麼我將不得不打破至少一個承諾。

同樣可以容納的方法:如果保留一份合同意味着打破其他合同,那麼它實際上是一個壞主意implement兩個interfaces

編輯:合同破碎,按照Class C signature應該實現兩個方法,但最終它只是一個method實施並忽略其他。

Reference

+0

你能解釋一下**合約在哪裏以及如何破碎嗎? – NINCOMPOOP

+0

合同破裂,按照C類簽名它應該實現兩種方法,但最終只能實現一種方法而忽略另一種方法。 –

+3

*它應該實現兩種方法* ???它應該實現一個聲明爲void test()的方法,第二個是哪裏? – NINCOMPOOP

6

JLS §8.4.8.4說,

與覆蓋等效簽名

這是可能的類繼承與多種方法繼承的方法超馳等效簽名(§8.4.2)
...
There可能是幾個路徑,通過這些路徑可以從接口繼承相同的方法聲明。這一事實不會造成任何困難,而且本身也不會導致編譯時錯誤。

看來理由是,如果一個類具有相同的名稱和簽名多個聲明,因爲類可能已經通過多個繼承了他們的路徑,實現一個接口,也繼承實現該接口的類,對例如 - 沒有傷害完成。

+0

如果方法的返回類型在兩個接口中不同,該怎麼辦? –

+0

@premktiw編譯錯誤。 JLS中的關鍵詞是*覆蓋等效簽名*。在覆蓋中更改返回類型是不合法的。 – andrewdotn

2
interface A 
{ 
void test(); 
} 

interface B 
{ 
void test(); 
} 
class C implements A, B { 

    public void test() 
    { 
     System.out.println("common to all"); 
    } 
    public A choose(A a){ 
     return new A(){ 
      public void test() { 
       System.out.println("test of A"); 
      } 
     }; 
    } 
    public B choose(B b){ 
     return new B(){ 
      public void test() { 
      System.out.println("test of B"); 
      } 
     }; 
    } 
} 
class Demo { 
    public static void main(String[] args) { 
    C c =new C(); 

    A a = new C(); 
    B b = new B(); 

    a = c.choose(a); 
    b = c.choose(b); 

    a.test(); 
    b.test(); 
    } 
} 
+4

沒有解釋的代碼不是答案 – BrDaHa

5

假設我們有兩個接口...

public interface StockBroker{ 
     //Give our client some investment strategies. 
     public String adviseClient(Client c); 
} 

public interface Doctor{ 
    //Examine our client and give them some medical advice 
     public String adviseClient(Client c); 
} 

和實現兩個接口的類....

public class JackOfAllTrades implements StockBroker, Doctor{ 
    public String adviseClient(Client c){ 
    } 
} 

雖然它可能是語法正確使用,以實現這兩個接口一種方法,你可能不會得到所需的行爲。例如,股票經紀人和醫生通常會給予他們的客戶極大不同的建議。

有人使用實現接口Doctor的對象期望adviseClient()方法提供醫療建議。但是有人使用實現接口StockBroker的對象期望adviseClient()方法發佈投資策略。

在這種情況下,對象JackOfAllTrades不知道發佈什麼類型的建議,因爲adviseClient()方法沒有參數,告訴它在調用adviseClient()時應該實現哪個接口。

這是Java的一個缺點,因爲設計接口的人可能無法知道別人會用相同的方法簽名來設計一個接口StockBroker

對於任何創建接口的人來說,使方法名稱足夠獨特以避免名稱衝突的方法很少見。

相關問題