2013-10-14 96 views
0

當我們在一個類中實現一個接口時,我們需要確保該接口定義的所有方法都出現在類的源代碼中。那麼爲什麼這個代碼很容易編譯?實現魔術

interface A { 
    void f(); 
} 
class X { 
    public void f() {} 
} 
class Y extends X implements A { 
} 
+2

爲什麼不應該呢? 'Y'從'X'繼承'f'方法並將其提升爲'public',這是允許的... – MadProgrammer

+0

如果某些接口方法沒有在派生類中實現,但它在基類中存在,因此它會查找定義從基類。 – SSP

回答

5

因爲X已經實現了f()方法,Y擴展X,這使得它繼承了該方法的實現。

對於這種情況,解決方案通過方法簽名進行。即使不實現A接口,類X也有一個具有正確簽名的方法。所以實現類Y也有這種方法。

我會說,有這樣的構造 - 雖然有效 - 只能在無法讓類X也實現接口(外部庫,代碼凍結,壞老闆等)時使用,因爲它讓人有些撓頭正在發生的事情......一個讀碼,必須導航到類X,並找到f()方法有...

首先我誤解的問題,而這些將是有效的,當X implements A也存在。
即使您已經明確指定X implements A條款,這並不重要 - 在這種情況下,這是多餘的。

如果X是抽象的,Y沒有實行f()Y將被迫實施的方法,除非Y聲明抽象了。

+0

您是否在談論「X實現A」記錄? – Alex

+0

這裏X實現了在你的界面中提供的方法 – SSP

+0

只是一個小小的評論 - 定義'implements'不是多餘的,因爲否則你將不能使用'Y'實例作爲'A'實例,即使它實現了必要的方法。 – Avi

2

如果某些接口方法未在派生類中實現,但在基類中存在,則將使用基類中的實現。

接口

interface A { 
    void f(); 
} 

基類

class X { 
    public void f() {} 
} 

在這裏,編譯器檢查方法f(),並且如果它的定義未在相同的類寫入,那麼它會尋找在基類定義。 這是繼承

派生類

class Y extends X implements A { 


} 

你可以把它理解爲f()是在Y類間接地存在的基本屬性。

首先編譯器將讀取Y類,那麼它會去對接A,然後它會在Y類搜索方法f()。如果它不那邊寫的,然後它會在基類中,這是x

+0

感謝大衛華萊士提高英語我將在未來照顧這些事情。 – SSP

0

從那裏你得到了聲明它必須是在類的源代碼搜索?

的類必須實現由實施interface或父(abstractclass定義的所有方法,否則必須聲明abstract

所以當然Y類會編譯。

0

在java中簡單的概念是孩子繼承其父的性質,如果是這種情況,那麼Y已經有f()可用。這不是魔術。

0

雖然類X沒有實現接口一個,它確實有這種情況發生,以匹配接口方法簽名的公共方法。 當類Y擴展類X它繼承該方法和編譯器將它視爲接口方法的有效實現。