Java:继承、实例变量和 this
我知道 this
是对当前正在执行的对象的引用。如果是这种情况,您能解释一下以下代码的行为吗?
public class Inherit {
public static class ClassA
{
private String privateInstanceVar = "Private";
public void classAMethod()
{
System.out.println("In class: " + this.getClass().getName());
System.out.println("Can access: " + this.privateInstanceVar);
}
}
public static class ClassB extends ClassA
{
}
public static void main(String[] args)
{
ClassB b = new ClassB();
b.classAMethod();
//Outputs:
//In class: Inherit$ClassB
//Can access: Private
//System.out.println(b.privateInstanceVar); // Fails to compile
}
}
classAMethod
的第一行报告 this
是对 ClassB
的引用。但是,在下一行中,我使用 this
来访问 ClassA
的私有实例变量 privateInstanceVar
,而我不应该访问该变量。 (被注释掉的 main
最后一行表明情况确实如此。)
所以,我的问题是:
- 如果
this
真的是对ClassB
的引用code>,如何从属于ClassB
的方法访问ClassA
上的私有实例变量? - 在执行时,
classAMethod
实际上是ClassA
和ClassB
的成员吗? - 如果 2. 的答案是肯定的,那么确定方法中任何给定行将在哪个上下文中执行的规则是什么?
- 如果 2. 的答案是否定的,那么对于代码的行为还有什么替代解释呢?
- 这里是否有一些我未能理解的更大的图景或微妙之处?
I understood that this
is a reference to the currently executing object. If that is the case can you explain the behaviour of the following code?
public class Inherit {
public static class ClassA
{
private String privateInstanceVar = "Private";
public void classAMethod()
{
System.out.println("In class: " + this.getClass().getName());
System.out.println("Can access: " + this.privateInstanceVar);
}
}
public static class ClassB extends ClassA
{
}
public static void main(String[] args)
{
ClassB b = new ClassB();
b.classAMethod();
//Outputs:
//In class: Inherit$ClassB
//Can access: Private
//System.out.println(b.privateInstanceVar); // Fails to compile
}
}
The first line of classAMethod
reports that this
is a reference to ClassB
. However, on the next line I use this
to access the private instance variable privateInstanceVar
of ClassA
, which I shouldn't have access to. (The commented out last line of main
shows that this is indeed the case.)
So, my questions are:
- If
this
really is a reference toClassB
, how can I access the private instance variable onClassA
from a method that belongs toClassB
? - Is
classAMethod
actually a member ofClassA
andClassB
at the point of execution? - If the answer to 2. is yes, what are the rules for determining in which context any given line in the method will execute?
- If the answer to 2. is no, then what alternative explanation is there for the behaviour of the code?
- Is there some bigger picture or subtlety here that I'm failing to appreciate?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
因为您从 classA 继承了该方法,并且该方法访问私有变量。
是的
编译时上下文:将选择您正在编写的代码中可见的方法或字段。示例:
new ClassB().getFoo()
将返回“bar”,而不是“phleem”,因为 ClassA 不知道 ClassB。Because you inherit the method from classA, and that method accesses the private variable.
Yes
Compile-time context: the method or field that is visible from the code you are writing will be chosen. Example:
new ClassB().getFoo()
will return "bar", not "phleem", because ClassA does not know about ClassB.我不确定你的困惑的根源是什么。它的工作原理完全符合人们的预期:
http://download.oracle.com/javase/tutorial/java/IandI /子类.html
I'm not sure what the source of your confusion is. It works exactly as one would expect:
http://download.oracle.com/javase/tutorial/java/IandI/subclasses.html
this
指的是 ClassB 实例,它也是一个ClassA
实例。方法classAMethod
是在ClassA
中定义的,因此可以访问ClassA
的所有私有成员。classAMethod
是ClassA
的方法,由ClassB
继承。this
refers to the ClassB instance, which is also aClassA
instance. The methodclassAMethod
is defined inClassA
, and thus has access to all theClassA
's private members.classAMethod
is a method ofClassA
, inherited byClassB
1)因为ClassB继承自ClassA,所以ClassA的所有public、protected方法对ClassB实例都是可见的。
2)是的。
3) 除非您在 ClassB 中重写 classAMethod,否则 ClassB 将只执行 CLassA.classAMethod()
5) 这是 Java 中继承工作的正常方式。
1) Because ClassB inherit from ClassA, so all public, protected method of ClassA are visible to ClassB instance.
2) Yes.
3) unless you override the classAMethod in ClassB, ClassB will just execute the CLassA.classAMethod()
5) This is the normal way inheritance works in Java.
ClassB
有权访问classAMethod()
,但无权访问privateInstanceVar
。因此,如果您尝试重写classAMethod()
,甚至定义一些其他尝试访问privateInstanceVar
的方法,您将会收到错误。为此,必须将该变量声明为受保护。ClassB
has access toclassAMethod()
but it does not have access toprivateInstanceVar
. So if you try to overrideclassAMethod()
or even define some other method which would attempt to accessprivateInstanceVar
you would get an error. The variable would have to be declared protected in order to do that.