Are the private members of superClass inherited by a subClass… Java?

拈花ヽ惹草 提交于 2020-01-13 05:42:31

问题


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...


回答1:


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.




回答2:


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 ....




回答3:


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



回答4:


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.




回答5:


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.



来源:https://stackoverflow.com/questions/14142737/are-the-private-members-of-superclass-inherited-by-a-subclass-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!