我正在阅读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字段提供编译时错误。我的问题是,第一点为什么编译器在继承了这个野蛮的领域时没有抱怨。为什么在访问时,它会给出这个问题?如果我们在使用类时也这样做,它允许。为什么不在接口的情况下。我的观点是它不应该只在第一时刻允许。澄清这个概念将非常有用。
答案 0 :(得分:9)
接口字段是隐含的最终静态。静态字段永远不会被继承。您可以通过定义具有相同名称的新字段来隐藏字段,但您只需要使用适当的接口限定字段名称以解决冲突:
PrintColors.YELLOW
或
RainbowCOlors.YELLOW
编辑:
澄清(希望):
编译器允许您在源代码中使用LotsOfColors.MAGENTA
,尽管该字段实际上是在PrintColors.MAGENTA
中定义的。但这只是为了让你的生活更轻松,特别是当你从子类中的超类引用一个字段时。
但是,在字节码中,编译器将对LotsOfColors.MAGENTA
的引用替换为PrintColors.MAGENTA
的引用。这一切都发生在编译时,而不是在运行时,就像多态方法一样。
当你有歧义时(比如LotsOfColors.YELLOW
),编译器无法决定你真正想要使用哪个字段。它可以是PrintColors.YELLOW
或RainbowColors.YELLOW
。因此,编译器不会做出任意决定,而是会产生编译错误,迫使您解决歧义。您可以通过提供实际的类名称PrintColors.YELLOW
或RainbowColors.YELLOW
来解决源代码中的歧义。
答案 1 :(得分:7)
接口中的字段默认为public static final
,因此它们不会被继承