3

I have gone through this:

Do subclasses inherit private fields?

But I'm still confused...

I'm talking about inheriting only and not accessing. I know that they aren't visible out side class.

But does the subclass' object has it's own copies of those private members in super class?

For example...

class Base {
    private int i;
}

class Derived extends Base {
    int j;
}

Now,

Base b = new Base();
Derived d = new Derived();

size of int is 4

Now,

Will the size of b be 4 and size of d be 8

or

size of d will also be 4 only ?

Of course I'm talking about the objects on the heap when I say b and d and not the references.

UPDATE: I just read in SCJP Book of Kathy Sierra & Bert... It says that they are NOT inherited.... I posted this update since still there are bunch of people saying yes...

Community
  • 1
  • 1
Sam
  • 1,842
  • 3
  • 19
  • 33
  • `private` members are not inherited but exist in the instantiated object in the parent (super). Your question is really about shadowing (I think? You seem to be talking about sizes of objects which doesn't apply in Java). See: http://stackoverflow.com/questions/3501060/can-parent-and-child-class-in-java-have-same-instance-variable – Brian Roach Jan 03 '13 at 16:18
  • Can you provide the the exact text that says that they are not inherited? I think there is confusion on terminology on this point. Per the Java specification, a subclass does not "inherit" private members of its superclass, but that is using a very strict notion of inheritance that's useful for the Java specification. Instances of that subclass will most certainly have its own instances of thoes memebrs. So, in this sense, the sense use in your question, they are inherited. – Nimrand Dec 24 '13 at 15:27
  • @Nimrand The exact text is: `When a member is declared private, a subclass can't inherit it.` In chapter 1 "Declarations and Access Control" under the section Private Members – Sam Dec 25 '13 at 11:11

5 Answers5

6

Yes, instances of the subclass will have copies of a private field of the parent class.

They will however not be visible to the subclass, so the only way to access them is via methods of the parent class.

mikera
  • 105,238
  • 25
  • 256
  • 415
4

Due to the JVM specification the class file is build this way:

ClassFile {
    u4             magic;
    u2             minor_version;
    u2             major_version;
    u2             constant_pool_count;
    cp_info        constant_pool[constant_pool_count-1];
    u2             access_flags;
    u2             this_class;
    u2             super_class;
    u2             interfaces_count;
    u2             interfaces[interfaces_count];
    u2             fields_count;
    field_info     fields[fields_count];
    u2             methods_count;
    method_info    methods[methods_count];
    u2             attributes_count;
    attribute_info attributes[attributes_count];
}

The super_class field consists:

`For a class, the value of the super_class item either must be zero or must be a valid index into the constant_pool table. If the value of the super_class item is nonzero, the constant_pool entry at that index must be a CONSTANT_Class_info (§4.4.1) structure representing the direct superclass of the class defined by this class file. Neither the direct superclass nor any of its superclasses may have the ACC_FINAL flag set in the access_flags item of its ClassFile structure.

If the value of the super_class item is zero, then this class file must represent the class Object, the only class or interface without a direct superclass.

For an interface, the value of the super_class item must always be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Class_info structure representing the class Object.`

More interesting is the fields[] part:

Each value in the fields table must be a field_info (§4.5) structure giving a complete description of a field in this class or interface. The fields table includes only those fields that are declared by this class or interface. It does not include items representing fields that are inherited from superclasses or superinterfaces.

So the compiled class doesn't contain inherited fields. On the other hand when an object is created the private super fields are in memory. Why? Let's imagine the example:

 classs A {
      int a;

      A(int a) {
          this.a = a;
      }

      void methodA() {
          System.out.println("A is: " + a);
      }
 }

 classs B extends A {
      int b;

      B(int b) {
          super(10);
          this.b = b;
      }

      void methodB() {
          super.methodA();
          System.out.println("B is: " + b);
      }
 }

The output should be: A is: 10 \n B is ....

Adam Sznajder
  • 9,108
  • 4
  • 39
  • 60
  • To be totaly honest this detailed explanation is a little bit too convoluted to answer the original question but gives great information about the inner workings of Java. +1 for class header structure in the explanation. – Igor Čordaš Apr 04 '14 at 17:13
1

Neither - the size of an object includes some overhead. But Derived will take more space than Base.

Running a quick test, it looks like the size of a Base is around 20 bytes and the size of a Derived is around 28 bytes. Note that these results can vary on a different JVM.

public static void main(String[] args) throws InterruptedException {
    int size = 500000;
    double mem;

    mem = Runtime.getRuntime().freeMemory();
    Base[] base = new Base[size];
    for (int i = 0; i < size; i++) {
        base[i] = new Base();
    }
    System.out.println((mem - Runtime.getRuntime().freeMemory()) / size);

    System.gc();
    Thread.sleep(100);
    System.gc();

    mem = Runtime.getRuntime().freeMemory();
    Derived[] derived = new Derived[size];
    for (int i = 0; i < size; i++) {
        derived[i] = new Derived();
    }
    System.out.println((mem - Runtime.getRuntime().freeMemory()) / size);
}
assylias
  • 321,522
  • 82
  • 660
  • 783
0

Yes, Derived class would have private field of Base class. If Derived defines public getters and setters you would be able to use that field from Derived class using it.

Will the size of b be 4 and size of d be 8 or size of d will also be 4 only ?

It is Java, not C. You cannot easily estimate size of object in the heap. It would be larger than just 4 or 8 bytes.

Nikolay Kuznetsov
  • 9,467
  • 12
  • 55
  • 101
0

No, private fields are designed to be accessible on the class where its declared. The only way for them to be accessible outside the class (that includes the derived class(es)) is through public methods.

If you want to make the members in the base class inherited by the derived class, use "protected" instead of private. The code should be:

class Base {
  protected int i;
}

class Derived extends Base {
  int j;
}

"Protected" Access modifier allows the member to be inherited and have it assigned its own access modifier.

winux
  • 452
  • 4
  • 12
  • You are absolutely correct... but what we are talking about is inheriting them and not about accessing them. – Sam Oct 14 '13 at 12:59
  • In that case if you want to inherit the base class members to your derived class, declare the members in the base class as "protected" – winux Nov 04 '14 at 07:57