简体   繁体   English

java中的继承私有字段

[英]inheritance private field in java

If a subclass can't inherit private members from a super-class, but it inherits public methods from the super-class that have access to the private members that are not inherited, as mentioned here 如果子类不能从超类继承私有成员,但它从超类继承了可以访问未继承的私有成员的公共方法,如此处所述

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

Where are the private members of the super-class that are modified by inherited members of the subclass stored? 存储了由子类的继承成员修改的超类的私有成员在哪里? Where do they exist? 它们存在于哪里?

Think of the private member variables as living in the class in which they are declared. 将私有成员变量视为生成在它们声明的类中。 If a subclass calls a method in its parent class that changes the member variable, think of that change as happening in the parent class. 如果子类调用其父类中更改成员变量的方法,请将该更改视为父类中发生的更改。 This is a useful way to model it in your head because only that parent class can have code that reads or writes that variable's value. 这是在头脑中对其进行建模的有用方法,因为只有该父类可以具有读取或写入该变量值的代码。

The subclass has to make a request to the parent class, then, to do something with the member variable declared up there. 子类必须向父类发出请求,然后对在那里声明的成员变量执行某些操作。

If you override a method in a parent class with code in the subclass, that override method can not access the private member variable, even though the overridden method in the parent does. 如果使用子类中的代码覆盖父类中的方法,则该覆盖方法无法访问私有成员变量,即使父项中的重写方法也是如此。 The overriding method in the subclass can call the overridden method in the parent though. 子类中的重写方法可以调用父类中的重写方法。

For example: 例如:

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)
    }
}

Low Level Info: 低级信息:

At a low level, though, I might create an instance of SubClass which will allocate a block of memory with room for all the instance variables for SubClass and all the parent classes up to, and including, Object. 但是,在较低的层次上,我可能会创建一个SubClass实例,它将为SubClass的所有实例变量和所有父类(包括Object)分配一块内存空间。

The code for the methods themselves lies in some memory allocated by some ClassLoader for the Class containing each method. 方法本身的代码在于某些ClassLoader为包含每个方法的Class分配的一些内存。 That is allocated on a class by class basis. 这是按类分配的。 So the various sub- and parent- classes' code isn't stored together even though the data is stored together in the instances. 因此,即使数据一起存储在实例中,各种子类和父类的代码也不会一起存储。

The rules of access just don't let the code in SubClass access the memory allocated for the instance variables that are private to a parent, or ancestor, class. 访问规则只是不让SubClass中的代码访问为父或祖先类私有的实例变量分配的内存。

In this case, though, it is seldom worth the effort of thinking about it in this much detail. 但是,在这种情况下,很少值得在这么多细节中考虑它。 That's my experience with it. 这是我的经验。 Others may see it differently. 其他人可能会有不同看法。

Note: There are ways to access private variables through reflection. 注意:有一些方法可以通过反射访问私有变量。

Visibility 能见度

I may need some help here as I'm working from memory. 我可能需要一些帮助,因为我在记忆中工作。

There are four levels of visiblity assigned to member variables. 为成员变量分配了四个级别的可见性。 These are the same four used with class variables and methods. 这些与类变量和方法一样使用。

private - these variables can be accessed only by code within the same class in which they are declared. private - 这些变量只能由声明它们的同一个类中的代码访问。 (Well ... they can be accessed by inner classes within that class too.) (嗯......他们也可以通过该类中的内部类访问。)

package - these can be accessed by code within the same class AND code in any class in the same package as that class. package - 这些可以通过同一个类中的代码访问,并且在与该类相同的包中的任何类中代码。 The class with that code could be in your source files or some jar file or, really, anywhere in the classpath. 具有该代码的类可以在您的源文件或一些jar文件中,或者实际上在类路径中的任何位置。 (Note: There is no keyword "package". A variable has package level visibility if there is no other keyword to indicate visibility. I like to put the word 'package' in a /* */ comment.) (注意:没有关键字“package”。如果没有其他关键字来表示可见性,则变量具有包级别可见性。我喜欢将“package”放在/ * * / comment中。)

protected - these can be accessed by code within the same class AND code in any subclass of that class AND code in any class in the same package as that class. protected - 这些可以通过相同类中的代码访问,并且可以通过该类的任何子类中的代码和与该类相同的包中的任何类中的代码访问。

public - these can be accessed by code within any other class. public - 可以通过任何其他类中的代码访问它们。

Warning: there are also ways that code you would otherwise expect to be visible is not. 警告:还有一些方法,否则您希望可见的代码不是。 This is because of the way the ClassLoader(s) work. 这是因为ClassLoader的工作方式。 Java EE has a nesting of class loaders and you can end up with code loaded by one class loader not being visible to code loaded by another one. Java EE具有类加载器的嵌套,您最终可能会遇到由一个类加载器加载的代码,这些代码加载器对另一个加载的代码不可见。 You can end up with two classes with the same full name (including package). 您最终可以使用两个具有相同全名的类(包括包)。 I consider all this an "advanced" topic and I'd have to read up on it to explain it. 我认为所有这些都是“高级”主题,我必须阅读它来解释它。 I did want to note that it happens and can cause you to wonder about visibility. 我确实想要注意它发生了,可能会让你想知道能见度。

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.

    ...
}

One final, practical note: I find it extremely useful in the long run to make almost all member variables private. 最后一个实际注意事项:从长远来看,我发现将几乎所有成员变量设为私有都非常有用。 If you need to change them from to something more visible, do so OR maybe just create getter and setter methods with the desired visibility. 如果您需要将它们更改为更明显的内容,请执行此操作,或者只创建具有所需可见性的getter和setter方法。 One advantage is that I can give readonly access if I provide a getter and no setter or if the getter is public and the setter is protected. 一个优点是,如果我提供一个getter而没有setter,或者getter是公共的并且setter受到保护,我可以给予readonly访问权限。 I can also make a writeonly variable that can be set but never read. 我也可以创建一个可以设置但永远不会读取的writeonly变量。 This works with dependency injection but you should put in a comment about that. 这适用于依赖注入,但你应该对此进行评论。 Maybe you can see the advantages. 也许你可以看到优势。 The disadvantage is you write more lines of code but eclipse among other IDEs will generate those methods for you if you like. 缺点是你编写了更多的代码行,但是如果你愿意,其他IDE中的eclipse会为你生成这些方法。

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

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

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