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;
}

它允许继承不明确的字段。但是当我尝试引用该字段并访问它时,它会给出编译时错误。为不明确的字段提供编译时错误。我的问题是,首先为什么编译器在继承模棱两可的字段时没有抱怨。为什么在访问时,它给出了这个问题?如果我们在使用类时也这样做,它允许。为什么不在接口的情况下。我的观点是它不应该只在第一时间允许。澄清这个概念将非常有帮助。

4

2 回答 2

9

接口字段是隐式静态最终的。静态字段永远不会被继承。您可以通过定义具有相同名称的新字段来隐藏字段,但您只需使用适当的接口限定字段名称即可解决冲突:

PrintColors.YELLOW

或者

RainbowCOlors.YELLOW

编辑:

澄清(希望):

编译器允许您LotsOfColors.MAGENTA在源代码中使用,尽管该字段实际上是在PrintColors.MAGENTA. 但这只是为了让您的生活更轻松,尤其是当您在子类中引用超类中的字段时。

但是,在字节码中,编译器将引用替换为对LotsOfColors.MAGENTA的引用PrintColors.MAGENTA。这一切都发生在编译时,而不是像多态方法那样在运行时发生。

当您有歧义时(例如 for LotsOfColors.YELLOW),编译器无法确定您实际要使用哪些字段。它可以是PrintColors.YELLOWRainbowColors.YELLOW。因此,编译器不会做出任意决定,而是会产生编译错误,以强制您解决歧义。您可以通过提供实际的类名来解决源代码中的歧义,要么PrintColors.YELLOW要么RainbowColors.YELLOW

于 2013-07-18T07:28:07.690 回答
7

默认情况下,接口中的字段public static final不会被继承

于 2013-07-18T07:26:25.703 回答