2017-08-09 74 views
3

讓我們假設我有這樣的代碼:爲什麼接口方法在實現接口的類中不能是靜態的?

public interface JustAnInterface { 
    void doSomething(); 
} 

public class JustAnInterfaceImplementation implements JustAnInterface { 

    @Override 
    public static void doSomething() { 

    } 
} 

爲什麼static doSomething()方法顯示錯誤「方法不從其超覆蓋法」?

+7

因爲在接口中定義的方法是非靜態的。你的問題基本上是循環的。 – EJP

+1

靜態方法通常無效。它們屬於它們所定義的類別,僅屬於該類別,並不構成層次結構的一部分。 – Michael

+1

方法簽名與接口不同。 –

回答

5

可以這樣說:因爲@Override和靜態根本就不在一起。

請記住:多態只適用於非靜態方法。 static表示您的方法「附加」到包含類。

換句話說:你知道關於靜態方法調用在編譯時的一切。但確定哪個重寫方法調用的過程發生在運行時。 Java中這兩個概念並不一致。

1

GhostCat所說的所有內容都是正確的,但@Override註釋並不是編譯錯誤的直接原因。

即使刪除它,該方法在編譯時無效。

您無法在派生類中添加static修飾符來覆蓋或實現方法,因爲覆蓋/實現僅對實例方法有效。
嘗試沒有註釋:

public class JustAnInterfaceImplementation implements JustAnInterface { 

    public static void doSomething() { 

    } 
} 

,您將有更具體的編譯錯誤比一個與@Override

方法不會覆蓋或超類型實現的方法

你應該得到這樣的東西:

壓倒一切的方法是靜態的

1

靜態和非靜態方法有不同的簽名,和static的不只是因爲。

非靜態方法在暗中採取一個額外的參數 - 值爲this

如果你熟悉Python,可以明確地看到這一點:

class SomeClass(object): 
    def doSomething(self): 
    pass // whatever method body 

這裏,self參數只是一個普通的參數:您可以調用該方法,並通過這個參數自己。

在Java中,它是一樣的。當您調用doSomething方法時,您會隱式傳遞一個參數,並且該參數將變爲this

但是,靜態方法需要參數。所以實際上,它們不是覆蓋等價的,因此你不能正確覆蓋該方法。

JVM必須以某種方式確定該參數應該丟棄。這種語言本來可以寫成允許的,但設計師採取了簡單的禁止它的路線(因爲無論如何都沒有理由使用它)。

相關問題