8

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?

Alex DiCarlo
  • 4,851
  • 18
  • 34
Aladdin
  • 221
  • 1
  • 3
  • 11

2 Answers2

10

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.

Lee Meador
  • 12,829
  • 2
  • 36
  • 42
  • it is great description of what happen under-hood , but you talk if that private member does not access , what about if it "hidden" , I mean if the subclass exist in the same package of super-class ? rather , ** what the different between not inherit private member and hidden private member ? ** – Aladdin Jan 25 '13 at 21:07
  • @Lee Meador I mean in the previous comment , as mentioned in oracle tutorial ......A subclass inherits all of the public and protected members of its parent, no matter what package the subclass is in. If the subclass is in the same package as its parent, **it also inherits the package-private members of the parent** – Aladdin Jan 25 '13 at 21:25
  • There's no such thing as an uninherited private member; they're always hidden. – Louis Wasserman Jan 25 '13 at 21:42
  • @Aladdin I have added to my answer in regard to visibility. What you called **package-private** is what I called **package** in the answer itself. It is not the same as **private**. – Lee Meador Jan 25 '13 at 21:46
  • @Lee Meador thanks a lot , you explain ambiguous confuse , that I had been fall in Unconsciously . – Aladdin Jan 25 '13 at 22:08
  • i think you're missing `extends Parent` in the declaration of `Derrived` – amphibient Feb 07 '13 at 16:02
  • i was slightly confused looking at it. the @Override would have failed – amphibient Feb 07 '13 at 17:12
7

An instance of the subclass contains all members of its superclasses, however private members may not be accessed from within the subclass.

Alex DiCarlo
  • 4,851
  • 18
  • 34
  • 1
    as mentioned in oracle tutorial **A subclass does not inherit the private members of its parent class. However, if the superclass has public or protected methods for accessing its private fields, these can also be used by the subclass.** [link](http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html) – Aladdin Jan 25 '13 at 20:35
  • Maybe inheritance isn't the best word, but any instance of a subclass still contains all members of the superclass, they are just not directly accessible. – Alex DiCarlo Jan 25 '13 at 20:40
  • @PaulBellora.. private members are not a part of subclass. Sub class doesn't inherit them. – Rohit Jain Jan 25 '13 at 20:41
  • @PaulBellora Its sort of right if you think about how it has to happen. I create an instance of SubClass which will allocate a block of memory with room for all the instance variable for SubClass and all the parent classes up to Object. The code for the methods lies in some memory allocated by some ClassLoader. The rules of access don't let the code in SubClass access the memory allocated for the instance variables that are private to a parent class. (But I prefer to model what's happening in my head as if SubClass only has its own member variables in it.) – Lee Meador Jan 25 '13 at 20:41
  • IMO, Inheritance and access are not the same thing. It's possible the tutorial used overly simple language. +1 *to the original answer*. – Paul Bellora Jan 25 '13 at 20:42
  • So, all the fields and methodds of super class, are stored as a part of super class only, with their modifiers specifying the range of accessibility of each member. – Rohit Jain Jan 25 '13 at 20:42
  • @RohitJain You are correct, I modified the language of my answer to reflect what I meant, apologies for any confusion this may have caused. – Alex DiCarlo Jan 25 '13 at 20:44
  • @RohitJain Almost right. All fields of super class are stored with the instance variables of the subclass (which is the one instantiated) and any of its parent classes. All methods (or, specifically, their compiled code) are stored as part of the super class, not the instance. – Lee Meador Jan 25 '13 at 20:49
  • @LeeMeador.. That makes perfect sense. I overlooked that method thing previously. :) – Rohit Jain Jan 25 '13 at 20:54
  • 1
    @LeeMeador Nitpick: I would say "with the instance of the subclass" - variables point to the instance. – Paul Bellora Jan 25 '13 at 20:55
  • 3
    This isn't the first time [this argument about the semantics of inheritance](http://stackoverflow.com/questions/4716040/does-subclasses-inherit-private-fields) has happened. – cyfur01 Jan 25 '13 at 21:02
  • @cyfur01 Thanks for the link - I guess I have to retract my opinion in the face of the JLS. – Paul Bellora Jan 25 '13 at 21:08