Java:继承,实例变量和这个

时间:2011-09-29 13:39:00

标签: java inheritance 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来访问privateInstanceVar的私有实例变量ClassA,这是我无法访问的。 (注释掉main的最后一行表明情况确实如此。)

所以,我的问题是:

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

5 个答案:

答案 0 :(得分:4)

  

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

因为你从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。

答案 1 :(得分:3)

我不确定你的困惑是什么来源。它完全按照预期的方式工作:

  

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

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

答案 2 :(得分:1)

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

答案 3 :(得分:0)

1)因为ClassB继承自ClassA,所以ClassA的所有公共受保护方法对ClassB实例都是可见的。

2)是的。

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

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

答案 4 :(得分:0)

ClassB可以访问classAMethod(),但无法访问privateInstanceVar。因此,如果您尝试覆盖classAMethod()或甚至定义其他尝试访问privateInstanceVar的方法,则会出现错误。为了做到这一点,必须将变量声明为受保护。