2013-07-18 2 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

Я не знаю историческую причину, но заметьте, что в примере не ** все ** константы неоднозначны. Итак, что произойдет, если вы хотите смешивать интерфейсы и использовать их без двусмысленных констант? –

ответ

9

полей Интерфейсных неявные статическим финала. И статические поля никогда не унаследованы. Вы можете скрыть поле, определив новое поле с тем же именем, но вам просто нужно квалифицировать имя поля с соответствующим интерфейсом для разрешения конфликта:

PrintColors.YELLOW 

или

RainbowCOlors.YELLOW 

EDIT:

для уточнения (надеюсь):

компилятор позволяет использовать LotsOfColors.MAGENTA в исходном сотрудничестве de, хотя поле фактически определено в 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

Хотя технически не унаследовано, вы МОЖЕТЕ получить к ним доступ косвенно, его просто не рекомендуется. Ошибка заключается в том, что два унаследованных интерфейса имеют одинаковые значения полей, компилятор не знает, какой из них имеет приоритет. –

Смежные вопросы