【问题标题】:why compilation fails for that example为什么该示例的编译失败
【发布时间】:2014-12-31 17:16:30
【问题描述】:

当我发现这个令人困惑的练习时,我正在处理 SCJP6 转储:

给定在两个不同文件中定义的类:

package packageA;

public class Message {

String getText() { return “text”; }

}

还有:

package packageB;

public class XMLMessage extends packageA.Message {

String getText() { return “<msg>text</msg>”;}

public static void main(String[] args) {

System.out.println(new XMLMessage().getText());

}

}

执行 XMLMessage.main 的结果是什么?

A. text

B. Compilation fails.

C. <msg>text</msg>

D. An exception is thrown at runtime.

答案是:B,但我不明白为什么;我认为答案应该是C。

【问题讨论】:

  • 尝试编译示例代码了吗?
  • 你试过运行它吗?
  • 你确定 2.5 行的某处没有@Override 吗?因为它确实编译和打印&lt;msg&gt;text&lt;/msg&gt;
  • 不,我只是编译它,它编译时带有警告,所以我想知道为什么它只有警告而不是编译器错误
  • 我只是运行它,它运行良好

标签: java inheritance polymorphism scjp ocpjp


【解决方案1】:

如果您发布的代码是书中的代码,那么您提到的正确答案是 C,让我解释一下原因。

再一次,假设您复制了本书中显示的代码,如下行:

String getText() { return “<msg>text</msg>”;}

它不会覆盖 packageA.Message 类中的 getText() 方法,而是声明一个新方法,该方法可以被 packageB 中的 XMLMessage 实例访问。

如果主要方法是这样的,这将是不同的:

 public static void main(String[] args) {

    Message message = new XmlMessage();
    System.out.println(message.getText());
}

在这种情况下会出现编译错误,因为 Message.getText() 方法没有暴露在包之外。

【讨论】:

  • 为什么它只是一个警告?更重要的是,我可以运行它并生成 text
  • 只要声明一个XMLMessage实例并访问packageB中的getText()方法,(就是这种情况)代码有效,输出为“text” ,您需要注意的非常重要的一点,就是我之前提到的,这不是覆盖 packageA.Message.getText()。
  • 感谢 jbarrueta 的所有解释,我同意你的看法。但是,我真的很想知道为什么在转储书中他们说 B 是正确答案,而您认为在真正的考试(SCJP 6)中答案将是“C”或者他们可能会犯这样的错误?
  • 我刚刚看到在中文版的转储中,答案是 c :)
【解决方案2】:

无法覆盖包默认方法,因为它在另一个包中不可见。 在您的示例中,Message 类中的方法 getText() 仅对 packageA 的成员可见。 Method does not override package visible method in Eclipse

【讨论】:

  • 感谢您的回复,但我认为由于 XMLMessage 无法看到 packageA.Message 中的方法,因此可以将其定义为新方法。为什么它只是一个警告?
  • 为什么它只是一个警告?更重要的是,我可以运行它并生成 text
  • 当我编译和运行代码时,我没有看到任何警告(反正在我的 IDE 中也没有)。 jbaruetta 是正确的 - 如果代码示例尝试从 Message 引用方法 getText() 而不是编译错误。我没有看到代码示例从 XMLMessage() 引用 getText 假设您对答案 B 的预测一开始是正确的:)
【解决方案3】:

String getText() { return “text”; } 方法是包(默认)范围。因此它在包 packageA 之外是不可见的。

因此无法覆盖 packageA 之外的 XMLMessage 类中的方法。

你可以在这里学习basics of method overloading and overriding

【讨论】:

  • 感谢您的回复,但我认为由于 XMLMessage 无法看到 packageA.Message 中的方法,因此可以将其定义为新方法。为什么它只是一个警告?更重要的是,我可以运行它并生成 text
猜你喜欢
  • 2013-05-14
  • 2019-07-26
  • 2016-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-29
  • 2014-04-09
相关资源
最近更新 更多