2012-03-25 243 views
16

我有兩個Java接口和一個實現類。Java類中實現相同方法簽名的兩個接口

(我已經使用Eclipse來直接運行程序,我沒有嘗試檢查任何編譯器通過命令行編譯明確警告等等。)

他們爲什麼不跑問題?爲什麼Java允許這樣做,即使它滿足兩個接口的「契約」但是在實現類時會產生歧義?

更新了示例。

public interface CassettePlayer { 
    void play(); 
} 

public interface DVDPlayer { 
    void play(); 
} 

public class CarPlayer implements CassettePlayer,DVDPlayer{ 

    @Override 
    public void play() { 
     System.out.println("This plays DVD, screw you Cassette !"); 
    } 

    public static void main(String args[]) { 
     CarPlayer cp = new CarPlayer(); 
     cp.play(); 

     CassettePlayer firstInterface = new CarPlayer(); 
     firstInterface.play(); 

     DVDPlayer secondInterface = new CarPlayer(); 
     secondInterface.play(); 
    } 
} 
+2

爲什麼他們應該不會有問題?這就是問題;) – 2012-03-25 20:46:00

+1

如果你希望你可以用'sayHello'方法創建一個抽象類,並使'Sample'擴展抽象類。這也不會有問題。 – emory 2012-03-25 20:51:26

+0

感謝哥們,我有同樣的問題... – orchidrudra 2012-09-07 06:07:41

回答

34

此方案特別允許在Java Language Specification, section 8.1.5

它允許在一類的單一方法聲明來實現多於一個超接口的方法。例如,在代碼:

interface Fish { int getNumberOfScales(); } 
interface Piano { int getNumberOfScales(); } 
class Tuna implements Fish, Piano { 
    // You can tune a piano, but can you tuna fish? 
    int getNumberOfScales() { return 91; } 
} 

方法getNumberOfScalesTuna類有一個名稱,簽名,並返回匹配接口Fish中聲明的方法,並且還在接口Piano聲明的方法相匹配的類型;它被認爲是同時實施。

的文本,然後接着指出,如果方法簽名有不同的返回類型,如doubleint,就沒有辦法實現在同一類和一個編譯時錯誤兩個接口將產生。

1

沒有衝突,因爲它們都指定了相同的合同,實現類只提供了一個方法,當通過任何接口引用調用它。

1

爲什麼不呢?這個類正在滿足兩個接口定義的契約。

1

該類實現了兩個接口 - 所以沒有問題。當然,在更復雜的情況下可能會導致意想不到的行爲,這種情況應該避免。

5

對於這個問題,有必要了解接口的用途。

接口是一種「契約」,以便知道哪個方法在具有該接口的類中被強制實現。所以如果你需要一個實現「DVDPlayer」的類(因爲你需要方法「play()」),你會發現CarPlayer。需要實施CassettePlayer的類也是如此。這是技術性的解釋。

但是,當然在你的語義編碼中,你應該確保CarPlayer的方法「play()」滿足DVDPlayer和CassettePlayer的語義。我認爲在實際應用中這將是一個不好的做法。

當然在你的例子中,有兩個接口聲明相同的方法是一個壞主意。更實際的情況是,你應該用「play()」方法制作了一個界面「Player」,並且還有另外兩個更具體的界面DVDPlayer和CassettePlayer(具有DVD和磁帶的特定方法)從Player繼承。另一方面,如果您不需要DVD或盒式磁帶的特定方法,那麼您不需要兩個不同的接口,只需要使用一個接口播放器就足夠了。

1

在這種情況下,沒有任何問題,因爲兩個接口具有相同的方法簽名。但是這個怎麼樣?

interface Animal { 
    public void eat() throws IOException; 
} 

interface Plants { 
    public void eat() throws NullPointerException; 
} 

哪一個是編譯器選擇的?爲什麼它會在代碼下面出錯?

public class Test implements Animal, Plants { 

    public void eat() throws IOException { 

    } 
} 

編譯器說:異常IOException異常是不兼容的throws子句中Plants.eat()

相關問題