2013-07-18 65 views
12

我正在經歷JLS第9.3.1節,並且我遇到了一個有趣的概念,即隱藏的繼承領域。這是來自JLS的示例接口不明確繼承字段

interface BaseColors { 
int RED = 1, GREEN = 2, BLUE = 4; 
} 
interface RainbowColors extends BaseColors { 
int YELLOW = 3, ORANGE = 5, INDIGO = 6, VIOLET = 7; 
} 
interface PrintColors extends BaseColors { 
int YELLOW = 8, CYAN = 16, MAGENTA = 32; 
} 
interface LotsOfColors extends RainbowColors, PrintColors { 
int FUCHSIA = 17, VERMILION = 43, CHARTREUSE = RED+90; 
} 

它允許有不明確的字段被繼承。但是,當我嘗試引用該字段並訪問它時,它會給編譯時間帶來錯誤。爲ambigious字段提供編譯時錯誤。我的問題是,起初爲什麼編譯器沒有抱怨,當這個隱藏的領域被遺傳時。爲什麼在訪問時間,這是給這個問題?如果我們在使用類時也是這樣,它允許。爲什麼不在接口的情況下。我的觀點是它不應該只在第一時間允許。澄清這個概念將非常有幫助。在接口

+2

我不知道歷史原因,但請注意,在例子中,不是所有**的常量都是模糊的。那麼,如果你想混合接口並使用它而沒有模棱兩可的常量,會發生什麼? –

回答

9

接口字段是隱含的靜態決賽。而靜態字段永遠不會被繼承。您可以隱藏字段定義具有相同名稱的一個新的領域,但你只需要使用適當的接口來限定字段名來解決衝突:

PrintColors.YELLOW 

RainbowCOlors.YELLOW 

編輯:

爲了澄清(希望):

編譯器允許您在源共同使用LotsOfColors.MAGENTA de,雖然該字段實際上在PrintColors.MAGENTA中定義。但這只是爲了讓你的生活變得容易一些,特別是當你從一個子類的超類中引用一個字段時。

但是,在字節碼中,編譯器通過引用PrintColors.MAGENTA來替換對LotsOfColors.MAGENTA的引用。這一切都發生在編譯時,而不是在運行時像多態方法。

當你有歧義(像LotsOfColors.YELLOW),編譯器不能決定哪個領域,你真的想使用。它可以是PrintColors.YELLOWRainbowColors.YELLOW。因此,編譯器會產生編譯錯誤,而不是採取任意決定,以迫使您解決模糊問題。您可以通過提供實際的類名稱來解決源代碼中的歧義問題,即PrintColors.YELLOWRainbowColors.YELLOW

+0

在上面的例子中,當我使用LotsOfColors.YELLOW時沒有。它在編譯時提供了模糊的錯誤。這就是我想要弄清楚的,如果它們沒有被繼承,爲什麼給出一個問題以及爲什麼即使出現在LotsOfColors中,因爲它們沒有被繼承。 – benz

+1

請參閱我編輯的答案。 –

+0

在我看來,這是一個設計錯誤,他們甚至允許'static'字段在子類或實現類中被引用爲不合格。 –

7

字段默認public static final所以他們不會得到繼承

+0

在上面的例子中,當我使用LotsOfColors.YELLOW時沒有。它在編譯時提供了模糊的錯誤。這就是我想要弄清楚的,如果它們沒有被繼承,爲什麼給出一個問題以及爲什麼即使出現在LotsOfColors中,因爲它們沒有被繼承。 – benz

+0

儘管技術上不會繼承,但您可以間接訪問它們,但不推薦。錯誤是當兩個繼承的接口都具有相同的字段值時,編譯器不知道哪一個優先。 –