【问题标题】:Cross-package inheritance with package/default access具有包/默认访问权限的跨包继承
【发布时间】:2017-05-05 22:28:53
【问题描述】:

在学习 OCJP 时,我遇到了这个令我惊讶的软件包问题。 我在各自的包 A 和 B 中有两个简单的类 Message 和 New Message,如下所示:

package A;
public class Message
{
    String getText()
    {
        return "text";
    }
}

以及包B中的NewMessage类和A的子类:

package B;
public class NewMessage extends A.Message
{
    String getText() {
        return "New Message";
    }

    public static void main(String[] args)
    {
        System.out.println(new NewMessage().getText());
    }
}

我编译为:

javac -d . Message.java
javac -d . NewMessage.java

并运行为:

java B.NewMessage

它会打印出来

 New Message

通过关注此堆栈帖子 Can a private method in super class be overriden in the sub-class? 我尝试用 @Override 标记 NewMessage 的方法并编译它,这给了我以下错误:

NewMessage.java:4: error: method does not override or implement a method from a supertype
        @Override
        ^

这意味着我没有覆盖getText() 方法。 有人可以向我解释这里发生了什么吗?这种情况是否类似于我链接的帖子中的私有方法覆盖的情况?

【问题讨论】:

  • 你看懂了吗?
  • @ItamarGreen 我的理解是这种行为与私有方法覆盖的行为相同。我知道默认可见性意味着它仅对默认包类可见和可访问。如果我想覆盖它,那么我需要在 A 类的 getText() 方法中添加“protected”修饰符。

标签: java oop inheritance packages


【解决方案1】:

发生这种情况的原因不同:

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

您正在创建一个具有该方法的NewMessage 对象。如果您创建了该对象,但它没有方法,但仍扩展 Message,则输出将为 'text'

【讨论】:

  • 事实上确实与不同包中的类有关。
  • @TimothyTruckle 有多精确?
【解决方案2】:

我认为这个问题的答案有你想要的:

In Java, difference between default, public, protected, and private

接受的答案引用了来自 oracle 的此文档:

http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html

由于默认范围仅适用于包,因此不允许您的子类覆盖它甚至访问它。如果您要从 NewMessage 类中删除 getText() 方法并尝试编译,您会发现 Message 类中的 getText 方法对 NewMessage 是不可见的。

我认为与您链接的帖子有相似之处,但不同之处在于仅授予包访问权限,因为未指定访问修饰符。

【讨论】:

    【解决方案3】:

    Message 类中的方法具有 默认 可见性,这意味着它仅在同一个包中可见。因此,对于其他包中的子类,它可见。

    由于该方法在包B 中不可见,因此无法覆盖我的NewMessage

    【讨论】:

      猜你喜欢
      • 2013-01-25
      • 1970-01-01
      • 2017-10-08
      • 2011-04-18
      • 1970-01-01
      • 1970-01-01
      • 2011-06-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多