Java:继承、实例变量和 this

发布于 2024-12-07 08:48:42 字数 1383 浏览 1 评论 0原文

我知道 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 最后一行表明情况确实如此。)

所以,我的问题是:

  1. 如果 this 真的是对 ClassB 的引用code>,如何从属于 ClassB 的方法访问 ClassA 上的私有实例变量?
  2. 在执行时,classAMethod 实际上是 ClassA ClassB 的成员吗?
  3. 如果 2. 的答案是肯定的,那么确定方法中任何给定行将在哪个上下文中执行的规则是什么?
  4. 如果 2. 的答案是否定的,那么对于代码的行为还有什么替代解释呢?
  5. 这里是否有一些我未能理解的更大的图景或微妙之处?

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:

  1. If this really is a reference to ClassB, how can I access the private instance variable on ClassA from a method that belongs to ClassB?
  2. Is classAMethod actually a member of ClassA and ClassB at the point of execution?
  3. If the answer to 2. is yes, what are the rules for determining in which context any given line in the method will execute?
  4. If the answer to 2. is no, then what alternative explanation is there for the behaviour of the code?
  5. Is there some bigger picture or subtlety here that I'm failing to appreciate?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

月下客 2024-12-14 08:48:42

如果这确实是对 ClassB 的引用,我如何访问私有的
来自属于 ClassB 的方法的 ClassA 上的实例变量?

因为您从 classA 继承了该方法,并且该方法访问私有变量。

此时 classAMethod 实际上是 ClassA 和 ClassB 的成员吗
执行?

是的

如果2.的答案是肯定的,那么判断的规则是什么
方法中的任何给定行将在哪个上下文中执行?

编译时上下文:将选择您正在编写的代码中可见的方法或字段。示例:

public static class ClassA{
    private String foo = "bar";
    public String getFoo(){return foo;}
}
public static class ClassB extends ClassA{
    private String foo = "phleem";
}

new ClassB().getFoo() 将返回“bar”,而不是“phleem”,因为 ClassA 不知道 ClassB。

If this really is a reference to ClassB, how can I access the private
instance variable on ClassA from a method that belongs to ClassB?

Because you inherit the method from classA, and that method accesses the private variable.

Is classAMethod actually a member of ClassA and ClassB at the point of
execution?

Yes

If the answer to 2. is yes, what are the rules for determining in
which context any given line in the method will execute?

Compile-time context: the method or field that is visible from the code you are writing will be chosen. Example:

public static class ClassA{
    private String foo = "bar";
    public String getFoo(){return foo;}
}
public static class ClassB extends ClassA{
    private String foo = "phleem";
}

new ClassB().getFoo() will return "bar", not "phleem", because ClassA does not know about ClassB.

不离久伴 2024-12-14 08:48:42

我不确定你的困惑的根源是什么。它的工作原理完全符合人们的预期:

子类不会继承父类的私有成员。但是,如果超类具有用于访问其私有字段的公共或受保护方法,则子类也可以使用这些方法。

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:

A subclass does not inherit the private members of its parent class. However, if the superclass has public or protected methods for accessing its private fields, these can also be used by the subclass.

http://download.oracle.com/javase/tutorial/java/IandI/subclasses.html

会发光的星星闪亮亮i 2024-12-14 08:48:42
  1. 是的,this 指的是 ClassB 实例,它也是一个 ClassA 实例。方法classAMethod 是在ClassA 中定义的,因此可以访问ClassA 的所有私有成员。
  2. 是的,classAMethodClassA 的方法,由 ClassB 继承。
  3. 一行在定义该行的类的上下文中执行。
  4. 不适用
  1. Yes, this refers to the ClassB instance, which is also a ClassA instance. The method classAMethod is defined in ClassA, and thus has access to all the ClassA's private members.
  2. Yes, classAMethod is a method of ClassA, inherited by ClassB
  3. A line executes in the context of the class in which this line is defined.
  4. Not applicable
忘年祭陌 2024-12-14 08:48:42

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.

那小子欠揍 2024-12-14 08:48:42

ClassB 有权访问 classAMethod(),但无权访问 privateInstanceVar。因此,如果您尝试重写classAMethod(),甚至定义一些其他尝试访问privateInstanceVar的方法,您将会收到错误。为此,必须将该变量声明为受保护。

ClassB has access to classAMethod() but it does not have access to privateInstanceVar. So if you try to override classAMethod() or even define some other method which would attempt to access privateInstanceVar you would get an error. The variable would have to be declared protected in order to do that.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文