繁体   English   中英

Java:继承,实例变量和this

[英]Java: inheritance, instance variables and 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最后一行中注释掉的事实表明确实如此。)

因此,我的问题是:

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

如果这确实是对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。

我不确定您感到困惑的原因是什么。 它完全可以像人们期望的那样工作:

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

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

  1. 是的, this是指ClassB实例,它也是ClassA实例。 方法classAMethod是在ClassA定义的,因此可以访问所有ClassA的私有成员。
  2. 是的, classAMethodClassA的方法,由ClassB继承
  3. 在定义该行的类的上下文中执行一行。
  4. 不适用

1)由于ClassB继承自ClassA,因此ClassB实例可以看到ClassA的所有公共受保护方法。

2)是的。

3)除非您在ClassB中重写classAMethod,否则ClassB将只执行CLassA.classAMethod()

5)这是Java中继承的正常方式。

ClassB可以访问classAMethod()但不能访问privateInstanceVar 因此,如果您尝试覆盖classAMethod()或什至定义其他尝试访问privateInstanceVar方法,则会收到错误消息。 为此,必须将变量声明为protected。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM