2013-07-18 10 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; 
} 

あいまいなフィールドが継承されるようにしています。しかし、フィールドを参照してアクセスしようとすると、コンパイル時にエラーが発生します。曖昧なフィールドのコンパイル時にエラーが発生する。私の質問は、曖昧なフィールドが継承されたときにコンパイラが不平を言っていない最初のポイントです。なぜアクセス時間に、それはこの問題を与えているのですか?クラスを使用するときに同じことをしても、それは可能です。なぜインタフェースの場合はありませんか?私の主張は、最初の瞬間にのみ許すべきではないということです。この概念の明確化はかなり役に立ちます。インタフェースで

+2

私は歴史的な理由はわかりませんが、この例では** all **ではなく、定数があいまいであることに注意してください。だから、あいまいな定数を使わずにインターフェイスをミックスして使用したい場合はどうなりますか? –

答えて

9

インターフェイスフィールドが暗黙的に静的な最終的なもので、デフォルトです。静的フィールドは決して継承されません。

PrintColors.YELLOW 

または

RainbowCOlors.YELLOW 

:あなたは同じ名前で新しいフィールドを定義することによって、フィールドを非表示にしていますが、単に競合を解決するために、適切なインタフェースで、フィールド名を修飾する必要がありますすることができますEDIT:

(うまくいけば)を明確にする:

コンパイラは、ソースの共同でLotsOfColors.MAGENTAを使用することができます実際にはフィールドはPrintColors.MAGENTAで定義されています。しかし、それはあなたの人生を少し楽にするためだけです。特に、サブクラスのスーパークラスからフィールドを参照するときは、そうです。

しかし、バイトコードでは、コンパイラはLotsOfColors.MAGENTAへの参照をPrintColors.MAGENTAへの参照で置き換えます。すべてがコンパイル時に発生し、実行時には多態的メソッドのようには発生しません。

LotsOfColors.YELLOWのように)あいまいさがある場合、コンパイラは実際に使用したいフィールドを決定できません。 PrintColors.YELLOWまたはRainbowColors.YELLOWにすることができます。したがって、任意の決定をする代わりに、コンパイラはコンパイルエラーを生成して、あいまいさを解消します。実際のクラス名をPrintColors.YELLOWまたはRainbowColors.YELLOWのいずれかで指定することで、ソースコードのあいまいさを解決できます。

+0

上記の例では、LotsOfColors.YELLOWを使用していません。コンパイル時にあいまいなエラーが出る。それは、私が理解しようとしているのは、継承されていない場合、なぜ問題を出すのか、なぜLotsOfColorsに継承されないので出現するのかです。 – benz

+1

私の編集した答えを見てください。 –

+0

私の意見では、設計上の間違いで、サブクラスや実装クラスで 'static'フィールドが非修飾型として参照されることさえ許されていました。 –

7

フィールドはpublic static finalので、彼らが継承され得ることはありません

+0

上記の例では、LotsOfColors.YELLOWを使用していません。コンパイル時にあいまいなエラーが出る。それは、私が理解しようとしているのは、継承されていない場合、なぜ問題を出すのか、なぜLotsOfColorsに継承されないので出現するのかです。 – benz

+0

技術的には継承されていませんが、間接的にアクセスすることはできますが、推奨されません。エラーは、継承されたインターフェイスのうちの2つが同じフィールド値を持つ場合、コンパイラはどちらが優先されるかを認識しません。 –

関連する問題