子类是不是从超类继承私有实例变量
Posted
技术标签:
【中文标题】子类是不是从超类继承私有实例变量【英文标题】:Do Subclasses Inherit Private Instance Variables From Superclasses子类是否从超类继承私有实例变量 【发布时间】:2012-05-16 11:41:58 【问题描述】:Do subclasses inherit private fields?
这个问题解决了同样的问题,但我不太明白它如何满足以下(看似)矛盾的情况。
http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html
表示“子类不继承其父类的私有成员。”
也就是说它既不继承私有实例变量也不继承私有方法对吧?
但是,如果它从其父级继承公共访问器方法,这将如何工作?它返回一个它不知道存在的实例变量?
此外,我的计算机科学书籍(Baron's AP Computer Science A)对“(子类)从(超类)继承所有私有实例变量和公共访问器方法”的问题提供了正确答案。
这不是oracle教程的缩影吗?
感谢您的帮助
【问题讨论】:
【参考方案1】:访问器可以正常工作。请记住,访问器在超类的“上下文”中运行,因此访问器将能够看到对子类隐藏的成员。
至于教科书,这取决于你的观点。子类继承了私有成员,因为它们实际上存在于子类的实例中(因此它们会占用内存等),但子类将无法直接访问它们。
【讨论】:
+1 是的,你的答案可以通过一个例子来强调:人类继承了(如果我们相信进化论)猴子的某种尾巴(底部骨头的一部分),但他们可以不要摇尾巴。他们只能看着猴子摇他们的故事,或者给他们香蕉来鼓励他们摇他们的故事。 这与私有方法的继承有何关系?它们是继承的但隐藏的吗?你不能使用(子类的对象)。(superclsas的私有方法)对吗?编辑:Lajos 就是一个很好的例子。 这与尾巴是猴子的私有成员有关,摇尾巴是一种私有方法,因为只有猴子才有尾巴,也只有它们才能摇尾巴。但是,有两种方法:第一种是观察猴子尾巴的公共方法,它在基类(Monkey)中定义,人类也可以访问,人类也可以看到猴子摇摆不定的故事,而第二种是私下给猴子送香蕉的方法,只有人类才能接触到,因为猴子是自私的,他们不会互相给香蕉。 我也给出了答案,你可以测试一下。 而摇尾是猴子的私有方法?因此不会被人类遗传?【参考方案2】:把它想象成洋葱。层次结构的每一层都是洋葱中的一层。例如,如果 C 类扩展了 B 类,而 B 类扩展了 A 类,那么 C 类的对象将如下所示:
Object of Class C
-------------------------------------------------------------
| |
| C and it's members |
| |
| ------------------------------------------------ |
| | | |
| | B and it's members | |
| | ------------------------------------ | |
| | | A and it's members | | |
| | | | | |
| | ------------------------------------ | |
| ------------------------------------------------ |
| |
-------------------------------------------------------------
所以,C 类的对象确实有 B 和 A 的成员。但它不能访问 B 和 A 的私有成员。
但是它可以访问 B 和 A 的公共和受保护成员。
因此 B 或 A 的公共访问器函数将允许 C 类的此对象访问 B 类或 A 类的私有实例变量“部分”对象。
【讨论】:
【参考方案3】:这里的“不继承”意味着您无法访问它。它仍然存在,只是不能以任何方式与您交互(通过调用超类的非私有方法除外)。
The accepted answer 在您链接到的问题中确实解释了这一点。该解释中是否有任何不明确的特定部分?
【讨论】:
不清楚的是为什么我的教科书说这是那个问题的答案。 它只是意味着与“继承”略有不同。【参考方案4】:当然,当你创建一个类B
的对象时,它继承自一个类A
,如果类A
有私有项,根据Java中的访问规则,你不能访问它们,但这些元素确实存在于私有内存中,如果它们是空对象,即使作为空引用也是如此。
在Java 语言规范中,您可以阅读:
类从其直接超类和直接超接口继承 超类和超接口的所有非私有字段 类中的代码都可以访问,并且不会被 类中的声明。
超类的
private
字段可能可供子类访问 - 例如,如果两个类都是同一个类的成员。 尽管如此,private
字段永远不会被子类继承。
【讨论】:
【参考方案5】:如果子类在同一个包中,它也继承私有成员,否则它只继承公共和受保护成员!
【讨论】:
【参考方案6】:私有成员也被继承。要对此进行测试,您可以在超类中执行以下操作:
//...
private String myText = "I'm in the superclass";
private void setMyText(String myTextValue)
this.myText = myTextValue;
public void setMyTextPublic(String myTextValue)
setMyText(myTextValue);
public String getMyText()
return myText;
//...
在继承的类中创建方法:
//...
public void setMyTextInTheSuperClass(String myTextValue)
System.out.println(getMyText());
setMyTextPublic(myTextValue);
System.out.println(getMyText());
public void setConstantValueToMyText()
setMyTextInTheSuperClass("I am in the child class");
//...
然后在某处调用 setConstantValueToMyText。
【讨论】:
我完全支持元语法命名方案,但在某些时候它可能会变得复杂。您可能应该将foobar
重命名为 setFoo
和 barfoo
重命名为 getFoo
。
@Jeffrey,你指出命名问题是绝对正确的,但是测试代码中的命名是没有任何意义的,目的是为了展示操作,他可能是我们正在谈论的新手任何成员和任何函数,而不仅仅是设置或获取值。但是,当您谈到“不要在家里尝试这个,您的命名应该有意义”的这些命名时,您是对的。
我认为大多数人都会有意识地不在实际代码中那样命名他们的方法,但是当我尝试按照您的示例进行操作时,我有点困惑。我只能想象对于初学者来说会有多混乱。
很公平,代码被修改了。也许现在更有帮助。
是的,你是对的。如果您尝试直接从继承的类中操作 myText,您的代码将无法编译。以上是关于子类是不是从超类继承私有实例变量的主要内容,如果未能解决你的问题,请参考以下文章
当子类被实例化时,超类的私有成员是不是也被实例化? [复制]