【问题标题】:Why private members are actually inherited by subclass为什么私有成员实际上是由子类继承的
【发布时间】:2018-07-27 17:28:49
【问题描述】:

我知道 Doc/Oracle 表明子类不会从超类继承私有成员。

但是在调试程序时,如果我们使用 ctrl F7 和 Ctrl F4 跟踪变量,我们肯定可以看到“私有成员被继承”。这很奇怪。

即使我用空的{} 覆盖默认构造函数,它实际上仍然继承私有成员,尽管私有成员不可访问。

术语和实际工作之间的混淆。

我创建了一个示例,包含三个类:

public class Inheritance {        

public static void main(String[] args) {

    teacher t1 = new teacher();
    t1.setGrd(80);
    System.out.println(t1.getGrd());
}
}


public class person {
    private int age=90;
    public void person(){

    }
}

public class teacher extends person {
    private int grade;

    public void setGrd(int age){
        grade=age;
    }
    public int getGrd(){
        return grade;
    }
} 

追踪时:

【问题讨论】:

  • 请发布您的代码。私有成员不被子类继承
  • 继承用于 is-a 关联。因此,如果 Fruit 具有私有字段颜色,则香蕉也具有私有字段颜色,因为它水果。但是从子类无法访问该字段的意义上说,它不是继承的:它无法读取或写入。它只有基类知道。
  • 你是说this the doc吗?它确实说“私有修饰符 - 该字段只能在其自己的类中访问。” ,但紧接的下一段是关于如何在子类中访问它:“这意味着它们只能从 Bicycle 类中直接访问。但是,我们仍然需要访问这些值。这可以通过添加公共方法来间接完成获取字段值”
  • "我知道 Doc/Oracle 指出子类不从超类继承私有成员。" 显示确切来源。
  • 我发布了代码,以及用于追踪的图片。请看一下。

标签: java debugging inheritance ide private


【解决方案1】:

我认为文档意味着子类无法查看/访问超类的私有成员。这并不意味着它们仍然不存在于超类中。调试器正在显示实例的完整状态,其中包括超类的私有状态。

【讨论】:

  • 实际上私有成员存在于子类的对象中。它是继承的。
【解决方案2】:

但是在调试程序时,如果我们使用 ctrl F7 和 Ctrl F4 跟踪变量,我们肯定可以看到“私有成员被继承”。

未继承 - IDE 显示类型层次结构的所有1 字段以帮助调试。它通过诸如遍历所有超类(getSuperclass)并收集所有字段(getDeclaredFields)之类的反射来实现。这里没有语言语义,这是一个“黑客”。

我不知道您使用的是什么 IDE,但“继承”标签并不是一个精确的词语选择,尽管它很好地表达了这一点。您可以向维护人员提交工单,要求使用更精确的词。

1 IDE 可以为您提供启用/禁用显示内容的选项,例如常量 (static final) 或 static 字段,它们也不会被继承。

【讨论】:

  • 非常感谢您的有用回复。我在想一件事:当我们只将一个子类实例化为'sub-obj'时,如果私有成员(prvt)没有被继承,为什么我们可以使用用户定义的getprvt()来获取值或者使用setprvt( ) 修改值。私有的“prvt”实际上已经存在于内存中。如果我们先 setter() prvt,然后我们可以 getter() 来获取修改后的值,这意味着 'prvt' 是为 sub-obj 保留的,而不是两个方法的局部变量。我对 Java 中的内存管理不太熟悉,对此不太确定。
  • @longe 如果您要询问内存模型,请发布另一个问题。您当前的问题询问您的 IDE 和文档之间的冲突。
【解决方案3】:

不继承私有成员肯定会违反Liskov subistution principle,所以我认为你理解错了。假设一个简单的例子:

public Foo {
  private int x = 50;
  public void yell() { System.out.println(x); }
}

public Bar extends Foo {

}

Bar bar = new Bar();
bar.yell();

如果private 字段没有被继承,这里应该发生什么?你发现你的推论有问题。 private成员都是继承的,但不能访问。

这听起来可能没用,但事实并非如此,因为您可以在超类型方法中实现很多功能,这些方法依赖于 ineriting 类不需要的内部状态。

【讨论】:

  • 我的问题是,Oracle 声明私有成员不会被继承。
猜你喜欢
  • 2013-10-23
  • 2016-12-12
  • 2018-06-14
  • 2022-01-04
  • 2011-01-02
  • 2012-12-25
  • 2013-02-12
  • 2013-08-30
  • 2020-09-04
相关资源
最近更新 更多