2016-08-24 52 views
2

這是一個顯示多重繼承的接口的例子。我想知道如何通過接口實現多重繼承,爲什麼我們不能按類使用它?編譯器如何知道應由obj.print()調用哪種打印方法?

interface Printable // interface1 
{ 
    void print(); 
} 

interface Showable //interface2 
{ 
    void print(); 
} 

class TestTnterface1 implements Printable,Showable 
{ 
    public void print() 
{ 
    System.out.println("Hello"); 
} 

public static void main(String args[]) 
{ 
    TestTnterface1 obj = new TestTnterface1(); 
    obj.print(); //which print method will be called now? 
} 
} 
+0

它會調用'TestTnterface1.print()'。接口沒有涉及到。你可以刪除'implements Printable,Showable',它仍然可以編譯,並且在執行時它仍然會調用TestTnterface1.print()。 – Andreas

回答

2

第一個問題:

實現同時滿足合同,所以不管你投你的具體類PrintableShowable,它將被用來一樣的。你會發現,有一個「不可能」的情況下,像這樣:

public interface Printable{ 
    String print(); 
} 

public interface Showable{ 
    void print(); 
} 

public class Impl implements Printable,Showable{ 
    /*impossible to implement because you cannot have the same method signature with two different return types*/ 
} 

多重繼承通常意味着有有用的每個父補上一。例如,如果Printable將使方法#printShowable具有方法#show,則繼承它們都會爲程序添加功能。

如果你想從幾個具體的類相結合的功能,你可能想看看composition instead of inheritance.

回答第二個問題更加棘手。你可以找到更長的討論here。儘管Java的創造者有可能投入這樣的選擇,但它會打開一些相當混亂的代碼。想想你給出的例子:如果PrintableShowable具有#print方法的具體實現呢?繼承類應該選擇哪種實現?

1

只有一個具體方法,其可稱爲

class TestTnterface1 implements Printable,Showable 
{ 
    public void print() 
    { 
     System.out.println("Hello"); 
    } 
1

在任何情況下運行將調用TestTnterface1#print()方法,因爲它是實施(可以執行的代碼)。

interface是合同一個這是實現必須遵循的,只有在編譯時使用了類。編譯器檢查實現者是否具有具有相同名稱和簽名的(非抽象)方法。

+0

爲什麼在運行時這兩種方法都不會有歧義?請簡要解釋。 –

+0

@Mayank Dudeja因爲接口中的方法沒有代碼(確切地說,在Java 8之前)。所以在運行時沒有歧義。在運行時只會有一個實現(在一個類中不能有多個具有相同簽名的方法)。 – PeterMmm

-2

由於兩個接口都有print()方法,而TestInterface1類有它的實現,所以它會調用它的實現。

public void print() 
{ 
    System.out.println("Hello"); 
} 
0

問題1:調用哪種方法?

只有一個方法實現可以實際調用。所以,沒有歧義。

問題2:我們如何通過接口實現多重繼承?

你已經爲此舉了一個例子。關於這種繼承的特殊之處在於不能有多個實現(直到Java 7)。與之相比,Java 8允許在接口中使用默認方法。

問題3:爲什麼我們不能按課程使用它?

它避免了狀態的繼承。

https://docs.oracle.com/javase/tutorial/java/IandI/multipleinheritance.html給出了一些更多信息。

相關問題