0

not to be stated as duplicate this question address where the field lives in the program not is it inherited or not or if it inherited but not accessible.

please continue reading to understand

in the example below we see that the dog object can access the animal private field "name" throw the use of a public getter "getName" but is not the private fields are not inherited so where the field name is living

from searching i realized that only one object is created from the sub class and not two one to the sub and one to the super to hold the private fields.

focus now >> we all know that a public setter in any class can set its private fields but we know where the field is living ! in the object of the class

so my question in abstract is as follow

where the accessed private field is living in the sub class created object !

Where is it !

public class Animal {
    private String name ;
    public Animal (String name)
    {
        this.name = name;
    }

    public String getName()
    {
        return this.name;
    }
}

public class Dog extends Animal {

    public Dog(String name) {
        super(name);
    }
}

public class Hello {
    public static void main(String[] args) {
        Dog mmms = new Dog("mmkk");
        System.out.println(mmms.getName());
    }
}

edit : i think this question may be stated as

where does the private fields of the parent class live if it is not inherited ?

question name changed for more understanding from

How the sub Class object get access to the private members of its super class from public getters?

to

Where do private fields of super class live when accessed from sub class using public getter ?

Sam
  • 239
  • 2
  • 12
  • 1
    You set the field in the `Animal` class when you called `super(name);` in the `Dog` class – takendarkk Mar 26 '18 at 21:21
  • i know i did but where is it in my object it is not inherited or it is ? – Sam Mar 26 '18 at 21:22
  • my question is focusing in the part of where is it and not how i did it but would be good to explain both – Sam Mar 26 '18 at 21:23
  • 3
    Object of the subclass contains private fields of the superclass. So in a sense they are inherited, you just can't access them in the subclass. – lexicore Mar 26 '18 at 21:28
  • no it is not the same if u read well u see i am saying where it is not if it is inherited it is a silly question – Sam Mar 26 '18 at 21:29
  • It is stored in the object you created because it is inherited - I don't know how to say it any different. – takendarkk Mar 26 '18 at 21:30
  • csmckelvey how it is inherited and it is private :) – Sam Mar 26 '18 at 21:32
  • If you read the linked question that is exactly what it explains. Private members are inherited by child objects, that's just how it works. – takendarkk Mar 26 '18 at 21:33

2 Answers2

1

Whenever an instance of a subclass is created, that is an instance of Dog in this case, constructors of all parent classes are called in a sequence allocating space required to store the state of the complete chain. In your case the super constructor is called explicitly, but even in an absence of an explicit call, an implicit call will be made provided there is a default constructor (if not then the code won't compile).

Information about the state of the parent instance state(s) is available and stored with the instance of the child. The way this information is stored depends on the JVM implementation with Oracle JRE being different from OpenJRE. However, it does not matter, that matter is that the child may not have access to fields or methods of the parent (in case of private fields or methods), but all fields are present and allocated a value, at least a default one. All methods are also present and are dispatched over based on vtable:

Instance methods are dispatched to those parts of the instance that correspond to the defining class. So if, in your case the class Animal defines getName and setName an no parent en-route to Dog redefines them, the JRE will execute the code with the state maintained by the part corresponding to Animal, thus setting or retrieving the name stored there. At the same time, all Java methods (including private), are virtual and, thus, can be overridden in subclasses. The information about such overrides will be persisted in the vtable responsible for dispatching. So if your class Dog redefines the getName and setName to do something else (it will not be able to access the field name from that class definition), then calling those methods on an instance of Dog will actually invoke methods defined in Dog rather than Animal. In this case you will likely lose any access to the field name within Animal (unless there are other getters/setters defined in Animal) even though the value that you put there in the constructor will remain stored.

As indicated elsewhere, one can still access private information via reflection or bytecode manipulation, but this would be done either rarely or for a very particular reason (e.g. the @Inject annotation on private fields is likely to result in setting a value via some injection framework). Even though this can be done, accessing private hidden (private, protected, package visible) methods or fields via reflection should be an exception rather than common practice as it obviously violates the original design decision.

Further reading:

Oleg Sklyar
  • 9,834
  • 6
  • 39
  • 62
  • thank for your respond it cleared some things – Sam Mar 26 '18 at 23:20
  • is not private methods are not virtual – Sam Mar 27 '18 at 05:55
  • All Java methods are virtual, private and non-private – Oleg Sklyar Mar 27 '18 at 06:10
  • all resources i read says that In Java, all non-static methods are by default "virtual functions." Only methods marked with the keyword final, which cannot be overridden, along with private methods, which are not inherited, are non-virtual. are you sure ! – Sam Mar 27 '18 at 06:58
  • Static and final are not virtual as neither can be overridden in subclasses. Privates seem to be dependent on the JVM implementation as the last link in my answer above indicates. This, however, makes no difference for your original question as this is merely runtime optimisation than a behaviour change. – Oleg Sklyar Mar 27 '18 at 07:11
0

There is only one instance of Dog which contains also the name instance variable because a Dog is an Animal and despite the fact that the field is not properly inherited from the parent class it is present in the instance.

What disturbs you is the fact that name isn't directly accessible from Dog code but it is there. It is just made to preserve encapsulation.

You can however read or modify this value by using a public or protected method of Animal, as getName() does or you can use reflection to achieve this goal:

Dog dog= new Dog("mmmk");
Field name = Animal.class.getDeclaredField("name");
name.setAccessible(true);
name.set(dog, "xxxxx");
System.err.println(dog.getName());

Now you can see that name's value has been modified to "xxxxx"

C.Champagne
  • 5,381
  • 2
  • 23
  • 35
  • thanks for explanation do you have an article that explains how this is done by virtual machine more – Sam Mar 26 '18 at 21:40
  • @Sam I'll try to find one but I can tell that the field is inherited. It is there as the other fields. It is just not accessible unless you use reflection. – C.Champagne Mar 26 '18 at 21:45
  • @Sam in fact I have read the link given as duplicate and there is a little nuance : the field is **NOT** inherited from the parent class but it **IS** present (though hidden) in the instance. – C.Champagne Mar 26 '18 at 22:00
  • thanks i will try to go further to know how – Sam Mar 26 '18 at 22:11