2011-08-23 125 views
10

好吧,我知道它的規則:爲什麼只能在頂級類中聲明接口?

根據JLS:8.1.3內部類和內附的情況下,內部 類可以不聲明靜態初始化或成員接口。 內部類可能不會聲明靜態成員,除非它們是編譯時常量字段 。

根據8.5.2靜態成員類型聲明,「會員接口 總是靜態的,它是允許的,但不是必需的 聲明成員接口明確列出靜態 修改」。他們永遠是頂級的,而不是內在的。

我只是想知道爲什麼。如果我們被允許在內部類中聲明接口,會發生什麼?如果我把它放到另一個Class文件中,內部類是不是會成爲頂級類?

回答

7

如果我把它放到另一個Class文件中,內部類是不是會成爲頂級類?

不,它仍然是一個內部類,其文件名錶示(IIRC它是OuterClass$InnerClass.class)。

內部類可以訪問外部類的屬性,即它們依賴於外部類的實例。有了接口,你不能這樣做。想想一個完全不相關的類,它必須由相應的外部類實例創建。如果外部類不知道誰實現了該接口,那麼這將如何完成?

你可以做什麼是你的外部類中,聲明靜態接口因此僅僅使用外爲命名空間:

public class OuterClass { 
    public static interface InnerInterface { //protected and private would be fine too, depending on what makes sense 
    } 
} 

編輯:其實,我誤解了問題,因爲接口是靜態的,反正,這裏是一個更新程式碼:

public class OuterClass { 
    public static InnerClass { //static inner class making OuterClass just be a namespace 
    public interface InnerInnerInterface { //protected and private would be fine too, depending on what makes sense 
    } 
    } 
} 

正如你可以定義一個抽象裏面的內類,與你必須堅持到單繼承約束的缺點,一種解決方法。

+0

嗯,有趣!我永遠不知道該接口可以聲明爲靜態的。這裏「靜態」是什麼意思?我試過谷歌靜態界面,但沒有發現任何東西。 P/s:只需在您引用的行編輯我的帖子,以糾正語法錯誤。 –

+2

@ W.N .:接口是隱式靜態的。該聲明只是減少。 –

+1

@Ryan好點,我也只是重讀這個問題,並會更新我的答案。 – Thomas

1

內部類應該是頂級類的實現細節,因此應該對客戶端不可見。您希望訪問內部類的任何功能都應該通過頂層類來完成,因爲從概念上講,該功能應僅作爲頂級類的功能可見,以便類設計者可以換出或以其他方式在不破壞客戶構建的情況下大幅改變內部類。

+2

這都是意見。如果內部類僅用於父類的內部使用,則不允許將它們設置爲「公共」。 – skaffman

2

根據定義,頂級類和它的內部類是緊密耦合的。接口是一種減少耦合的手段。

+1

即使我只需要爲內部類私下使用該接口? –

+0

這不一定是一個好的參數,因爲我已經編寫了一些私有的嵌套接口,這些接口僅在單個類的範圍內使用。 –

4

從靜態和非靜態的角度來看待它。 「頂級」類建立了一個靜態上下文,因爲它可以在沒有任何封閉實例的情況下被訪問。即您可以從主要方法訪問頂級類。這同樣適用於頂級類的任何靜態成員。但是,內部類既不存在於*也不建立任何靜態上下文。因此它不能有任何靜態成員,並且只能通過其包含類的實例(如構造函數和其他實例成員)來訪問它。從主要方法來看,你不能說Outer.Inner。SOME_FIELD,因爲內部類的成員只對含有類有意義。

*種類

+0

這個答案會讓托馬斯的答案更清晰。 +1。 –

相關問題