如果具有相同名称的字段从两个源(类和接口)继承,将会发生什么

时间:2014-05-22 15:01:51

标签: java inheritance interface field implementation

有效代码:

interface Int1{
    String str = "123";
}
class Pparent{
    String str = "123";  
}
class F extends Pparent implements Int1{       
}

无效代码

将主要方法添加到F类:

class F extends Pparent implements Int1{
      public static void main(String[] args) {
        System.out.println(str);
    } 
}

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
  The field str is ambiguous

  at test.core.F.main(NullReferenceTest.java:45)

我不认为这两种变体都有惊人的不同之处。 我准备scjp并要求澄清所有相关情况。当我看到熟悉的问题时,我很乱。

你能澄清一般规则吗?

4 个答案:

答案 0 :(得分:2)

标识符str可以引用两个字段 - 从Int1继承的静态字段和从Pparent继承的实例1。即使尝试使用来自静态上下文的实例1无效,该名称仍然可以解析。 (如果Pparent.str是静态的,您仍然会收到错误消息。)

两个字段都没有隐藏另一个字段,因为它们是从不同的父母继承的 - 因此名称含糊不清。编译器抱怨,因为它不知道你指的是哪个字段。

如果您想要来自Int1的那个,只需符合条件:

System.out.println(Int1.str);

如果你想要来自Pparent的那个,你应该创建一个实例并将其转换为Pparent,以明确你 指的是接口字段:

System.out.println(((Pparent) new F()).str);

显然这很糟糕,你应该避免首先陷入这种情况。这部分是通过将所有字段设为私有来实现的,除了常量。在超类和想要实现的接口中有两个具有完全相同名称的常量是非常罕见的。

答案 1 :(得分:1)

str的{​​{1}}字段隐含interface Int1 staticpublic

final类的str字段是一个实例字段。

当您引用Pparent时会发生什么情况,您对实例字段和类字段有一个模棱两可的引用,因此错误。

答案 2 :(得分:0)

我认为这是不允许的,因为 str 的值在您的PParent课程和Int1之间不明确,这会给你你正在获得的编译时错误。这是一个多重继承变量的案例。

答案 3 :(得分:0)

您正在尝试在Eclipse中运行有错误的代码。 Eclipse生成代码以生成该消息。

您正在调用Eclipse生成的代码。您的原始源是错误的,因此Eclipse编译器无法编译它 - 而是生成了显示问题中的消息的字节代码。

实际上,这是编译时错误。