【问题标题】:Java accessing private superclass member through protected getterJava通过受保护的getter访问私有超类成员
【发布时间】:2016-05-22 19:27:47
【问题描述】:

我知道在 Java 中,只要超类提供公共或受保护的 getter 方法,您就可以在子类中访问超类的私有成员。然而,我也知道子类实际上并没有继承私有成员。考虑以下情况....

Class A {
    private var = 2;
    protected int getVar(){
        return var;
    }
}

Class B extends A{

   public void printVar(){
       System.out.println(getVar());
   }
}

Class Main{

    public static void main(args []){

         B b= new B();
         b.printVar();
    }
}

我想了解,既然我们正在创建子类 B 的实例,那么该私有成员究竟是什么时候以及何时分配给内存的,它的范围是什么?既然 A 的实例实际上从未被创建,它是如何存在的?它不是静态变量,也不是最终变量,所以它是动态堆栈还是隐式堆动态?我认为,当您从超类实例化子类时,您也会继承非私有的成员和方法,然后将这些成员实例化为子类的对象实例的一部分(除非它们被覆盖等),所以只有一个对象被分配为堆动态变量。但是,如果这些私有成员没有被继承,那么编译器是否只是为它们提供堆栈动态引用以防调用继承的 getter 方法并且仅在这种情况下?

【问题讨论】:

    标签: java class oop inheritance access-modifiers


    【解决方案1】:

    不过我也知道子类实际上并没有继承私有成员。

    是的。 B 的实例A 的实例,它包含所有相同的字段。您无法再直接访问私有字段,但它们仍然存在。

    由于实际上从未创建过 A 的实例,它是如何存在的?

    当您创建B 时,A 中的构造函数也会被调用,以确保将B 实例正确初始化为有效的A。不要将子类视为与超类不同的东西。 B 仍然是 A;它只是做得更多。

    【讨论】:

      【解决方案2】:

      您认为超类的私有成员不被子类继承的假设是错误的。所有成员都是继承的。子类的私有成员是子类实例的一部分,但不能通过子类的代码直接访问。

      在返回私有成员的值的超类中有一个受保护的 getter 为子类提供了一种访问私有成员值的方法(尽管它不能修改它,除非你也有一个受保护的或超类中的公共二传手)。

      【讨论】:

      • 尽管根据 JLS .... .还是我误解了这个? (docs.oracle.com/javase/specs/jls/se5.0/html/classes.html#8.2):声明为私有的类的成员不会被该类的子类继承。只有声明为受保护或公共的类的成员才能被声明在包中的子类继承,而不是在其中声明该类的那个。
      • 啊,没关系,仔细看后,我不明白它在说什么。
      • @LorenShqipognja 我想这是一个解释问题。通过“不继承”,JLS 意味着子类不能访问私有成员。它们仍然由超类的代码分配和初始化。
      • 就我的问题而言,但是您的解释是正确的,谢谢:)
      • 您好 Eran,我认为您的回答中有一个小错字。 “子类的私有成员是子类实例的一部分”应该是“超类的私有成员是子类实例的一部分”
      猜你喜欢
      • 2016-07-15
      • 2012-12-01
      • 2013-10-16
      • 2012-05-03
      • 1970-01-01
      • 1970-01-01
      • 2016-08-13
      • 2017-08-01
      • 2016-10-01
      相关资源
      最近更新 更多