Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

inheritance private field in java

Tags:

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

Where are the private members of the super-class that are modified by inherited members of the subclass stored? Where do they exist?

like image 699
Aladdin Avatar asked Jan 25 '13 20:01

Aladdin


1 Answers

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.

The code for the methods themselves lies in some memory allocated by some ClassLoader for the Class containing each method. 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.

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. (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. The class with that code could be in your source files or some jar file or, really, anywhere in the classpath. (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.)

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.

public - these can be accessed by code within any other class.

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. 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. 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. 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. I can also make a writeonly variable that can be set but never read. 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.

like image 185
Lee Meador Avatar answered Sep 19 '22 12:09

Lee Meador