【问题标题】:what will happen if fields with same name inherites from two sources(class and interface)如果具有相同名称的字段继承自两个源(类和接口)会发生什么
【发布时间】:2014-05-22 15:01:50
【问题描述】:

有效代码:

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

无效代码

在F类中添加main方法:

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 并要求澄清所有相关情况。当我看到熟悉的问题时,我一头雾水。

你能澄清一下共同的规则吗?

【问题讨论】:

  • @Sotirios Delimanolis ideone.com/gMqUpe
  • @Sotirios Delimanolis 在链接中写道 编译器!对 str 的引用不明确,Pparent 中的变量 str 和 Int1 中的变量 str 匹配
  • @Sotirios Delimanolis 在我的问题中:未解决的编译问题*。我认为线程 main 中的异常 - 它是 eclipse 包装器)Eclipse - 坏男孩)
  • @SotiriosDelimanolis:并不是编译的类不同步。即使编译失败,Eclipse 仍然会发出类文件,并允许您尝试运行代码(通常带有警告对话框)。
  • @JonSkeet 我明白了。我认为它是在使用没有字段的接口编译时发生的。然后添加字段,重新编译接口并尝试运行该类。我意识到如果类在没有接口字段的情况下编译,它将引用字节码中的实例字段,所以我的建议不会发生。

标签: java inheritance interface field implementation


【解决方案1】:

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

两个字段都没有隐藏另一个字段,因为它们是从不同的父母那里继承而来的——所以这个名字是模棱两可的。编译器抱怨是因为它不知道你指的是哪个字段。

如果你想要来自Int1 的那个,只需限定它:

System.out.println(Int1.str);

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

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

显然这很可怕,您应该首先避免陷入这种情况。这部分是通过将所有字段设为私有(常量除外)来实现的。在您要实现的超类和接口中同时拥有两个名称完全相同的常量是很不寻常的。

【讨论】:

  • 这对我来说很奇怪,因为在我的示例中,类的实例不存在。逻辑上获取可用的静态变量
  • @gstackoverflow:我知道这在某些方面会很有用,但我认为这不是语言的定义方式。 确切地指出在规范中的哪个位置指出虽然......
【解决方案2】:

interface Int1str 字段隐含为 static publicfinal

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

当您引用 str 时会发生什么是您对实例字段和类字段的引用不明确,因此会出现错误。

【讨论】:

    【解决方案3】:

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

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

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

    【讨论】:

      【解决方案4】:

      我认为这是不允许的,因为 str 的值在您的 PParent 类和 Int1 之间会模棱两可,这会给您带来编译时错误你现在得到了。这是一个变量多重继承的例子。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-01-23
        • 1970-01-01
        • 1970-01-01
        • 2011-05-29
        • 2020-12-09
        • 2021-10-01
        相关资源
        最近更新 更多