java中的继承私有字段

时间:2013-01-25 20:31:23

标签: java

如果子类不能从超类继承私有成员,但它从超类继承了可以访问未继承的私有成员的公共方法,如下所述

  

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

由子类的继承成员修改的超类的私有成员在哪里?它们存在于哪里?

2 个答案:

答案 0 :(得分:9)

将私有成员变量视为生成在声明它们的类中。如果子类调用其父类中更改成员变量的方法,请将该更改视为父类中发生的更改。这是一种在头脑中建模的有用方法,因为只有那个父类可以拥有读取或写入该变量值的代码。

子类必须向父类发出请求,然后对在那里声明的成员变量做一些事情。

如果使用子类中的代码覆盖父类中的方法,则该覆盖方法无法访问私有成员变量,即使父项中的重写方法也是如此。子类中的重写方法可以调用父类中的重写方法。

例如:

public class Parent {
    private int bar = 0;
    public void setBar(int value) {
        bar = value;
    }
}

public class Derived extends Parent {
    @override
    public void setBar(int value) {
        bar = value + 1; // NOT ALLOWED
        super.setBar(value + 1); // ALLOWED (same result)
    }
}

低级信息:

但是,在较低的层次上,我可能会创建一个SubClass实例,它将为SubClass的所有实例变量和所有父类(包括Object)分配一块内存空间。

方法本身的代码在于某些ClassLoader为包含每个方法的Class分配的一些内存。这是按类分配的。因此,即使数据一起存储在实例中,各种子类和父类的代码也不会存储在一起。

访问规则只是不要让SubClass中的代码访问为父或祖先类私有的实例变量分配的内存。

在这种情况下,很少值得在这么多细节中考虑它。这是我的经验。其他人可能会有不同的看法。

注意:有一些方法可以通过反射访问私有变量。

<强>可见性

我可能需要一些帮助,因为我在记忆中工作。

为成员变量分配了四个级别的可见性。这些与类变量和方法一样使用。

private - 这些变量只能由声明它们的同一个类中的代码访问。 (嗯......他们也可以通过该类中的内部类访问。)

包 - 这些可以通过相同类中的代码和与该类相同的包中的任何类中的代码访问。具有该代码的类可以在您的源文件或一些jar文件中,或者实际上在类路径中的任何位置。 (注意:没有关键字“package”。如果没有其他关键字来表示可见性,则变量具有包级别可见性。我喜欢将“package”放在/ * * / comment中。)

protected - 这些可以通过相同类中的代码访问,并且可以通过该类的任何子类中的代码访问,并且在与该类相同的包中的任何类中代码。

public - 可以通过任何其他类中的代码访问它们。

警告:还有一些方法,否则您希望可见的代码不是。这是因为ClassLoader的工作方式。 Java EE具有类加载器的嵌套,您最终可能会遇到由一个类加载器加载的代码,这些代码加载器对另一个加载的代码不可见。您最终可以使用两个具有相同全名的类(包括包)。我认为所有这些都是“高级”主题,我必须阅读它来解释它。我确实想要注意它发生了,并且可能会让你怀疑能见度。

public class MyClass {
    private int foo1 = 1;       // visible in this class only
    protected int foo2 = 2;     // visible here, in subclasses and in classes with same package
    int foo3 = 3;               // visible here and in classes with the same package
    public int foo4 = 4;        // visible here, there and everywhere

    /* package */ int foo5 = 5; // how I like to do 'package' variables with a comment
                                //  to show I intended to do it on purpose. If you read
                                //  my code you don't have to wonder if I forgot it.

    ...
}

最后一个实际的注意事项:从长远来看,我发现几乎所有成员变量都是私有的非常有用。如果您需要将它们更改为更明显的内容,请执行此操作,或者只创建具有所需可见性的getter和setter方法。一个优点是,如果我提供一个getter而没有setter,或者getter是公共的并且setter受到保护,我可以给予readonly访问权限。我也可以创建一个可以设置但永远不会读取的writeonly变量。这适用于依赖注入,但你应该对此进行评论。也许你可以看到优势。缺点是你编写了更多的代码行,但是如果你愿意,其他IDE中的eclipse会为你生成这些方法。

答案 1 :(得分:7)

子类的实例包含其超类的所有成员,但是可能无法从子类中访问 private 成员。