2013-12-14 35 views
0

而不是談論理論,讓我直接跳到這個例子來說明我想問什麼。類是如何考慮它的超類的方法,因爲它的接口方法的實現?

// The below piece of code is present in a single java file named "MyMain.java" 
public class MyMain { 
    public static void main(String args[]) { 
     IFace iFace = new CSub(); 
     iFace.method(); // This method essentially belongs to CSuper which doesn't implement IFace 
    } 
} 

interface IFace { 
    void method(); // Method in the interface 
} 

class CSuper { 
    public void method(){ // some method in this class, but not the one which implements the method of IFace 
     System.out.println("I'm not implementing IFace's method"); 
    } 
} 

class CSub extends CSuper implements IFace {} // No method implemented in the class and yet no error. 

顯然上面這段代碼的工作,因爲我是能夠得到輸出我不是在執行時實現IFACE的方法

我的問題是,如何CSub採取CSUpermethod()IFace接口method()的實施。這似乎是繼承,但我需要一些具體的答案。還有,這是否有一個JLS參考可以通過繼承來闡明這是如何實現的?


而對於一個跟進的問題是,說有某種原因,爲什麼這個工作(正如我猜,這是繼承,但需要確保這件事),爲什麼不相同的代碼如果我執行以下任何一項更改,代碼段工作?

變化1:

class CSuper { 
    void method(){ // there is no access specifier, thus default(package) 
     System.out.println("I'm not implementing IFace's method"); 
    } 
} 

變化2:

class CSuper { 
    protected void method(){ // access specifier is now protected 
     System.out.println("I'm not implementing IFace's method"); 
    } 
} 

對於上述兩種變化我做什麼,我得到一個編譯錯誤說繼承的方法CSUper.method( )canoot隱藏IFace的公共抽象方法

class CSub extends CSuper implements IFace {} 

這是爲什麼?由於它是繼承,所以protected默認訪問說明符應該工作,因爲所有的類都存在於同一個文件中。 method()必須繼承到CSub類,就像它在問題的第一部分中所做的一樣。任何人都可以突出這個案例嗎?

+0

你讀過[this](http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html)嗎? –

回答

2

第1部分的答案很簡單 - 接口只需要接口所屬的類實現具有該特徵的方法。

它並不關心方法實際定義的位置 - 只要它存在,那麼接口是有效的。

其原因也相當明顯。所有界面都在說「任何具有此界面的對象,您都可以使用參數Y調用一個名爲X的函數,它將返回Z」。通過從超類中繼承該方法,您即可滿足該要求。

這也回答了第2部分。要實現一個接口,實現方法必須是公共的 - 任何人都可以訪問它。

通過使超類方法包私有或保護它不再符合要求。

class CSub extends CSuper implements IFace { 
    public method() { 
     super.method(); 
    } 
} 

通過這樣做,你可以做的方法public(進行訪問通過繼承更廣闊的是允許的,你不能讓事情變得更受限制),現在將再次滿足該接口。

訪問限制是方法簽名的一部分。解釋爲什麼要考慮一個班級遞交IFace x。然後他們會嘗試撥打界面中定義的x.method()

如果它們與您的實施不在同一個包中,它們仍然需要能夠呼叫x.method()。因爲這個x.method()必須公開才能滿足界面 - 否則人們可以得到一個IFace,但該方法將不可用。

+0

那麼這部分回答了我的問題。儘管我還要再問幾個問題。是否有JLS文檔說明滿足所需簽名的方法不一定來自實現接口的類,並且它可以來自超類?我覺得這是正確的,但我只需要一些記錄的證據來確定。另外,在這種情況下,我的問題的第二部分會發生什麼? – SudoRahul

+0

看到我的編輯,剛回答第二部分。 –

+0

即使它是私有的還是受保護的,子類中存在具有相同簽名的方法吧?它從CSuper繼承到'CSub',因爲它不是私有的。如果訪問說明符是私人的,我可以明白爲什麼它不起作用,但我覺得即使它受到保護或具有默認訪問權限,它也應該可以工作。 – SudoRahul

4

蒂姆的回答大部分。對於JLS參考,從section 8.1.5

除非所聲明的類是抽象的,每個直接超接口的所有方法成員的聲明必須通過在這個類中聲明或由現有的方法聲明來實現繼承自直接超類,因爲不抽象的類不允許有抽象方法(§8.1.1.1)。

相關問題