27

Suppose I have two classes Parent and Child, and Child inherits from Parent. I have three methods in Parent, out of which two are public and one is private.

Normally we say that all the non-private methods are inherited into the Child class, but I'm confused about exactly what happens. Does Java make a copy of the methods in the Child class, or does it use some kind of reference to maintain the relationship?

class Parent{
    // Private method
    private void method1(){
        System.out.println("In private method of Parent class");
    }
    void method2(){
    // calling private method
        method1();
    }
    void method3(){
    // calling private method
        method1();
    }
}

class Child extends Parent{

}

class MainClass{
   public static void main(String[] args){
       Child child = new Child();
       // calling non-private method which internally calls the private method
       child.method2();
   }
}
Chris Martin
  • 30,334
  • 10
  • 78
  • 137
Harshit Gupta
  • 719
  • 1
  • 9
  • 26

4 Answers4

11

Does Java makes copy of the methods in the Child class or it uses some kind of reference to maintain the relationship?

Latter. Take a look at invokespecial. Java recursively looks up methods one class at a time. The first matching method is called. This is why calling a virtual (default) method is slower than calling a final method.

In general, the actual code within a method is not copied when you inherit from a class containing that method.

Navin
  • 3,681
  • 3
  • 28
  • 52
  • 1
    I think one of the interesting parts that should be explained is about private variables, which are not inherited, yet still exist "somewhere" in every instance of the child class. – RealSkeptic Sep 08 '15 at 10:51
  • @RealSkeptic Yup, I'm only talking about methods. Inheritance is hairy enough as it is :P – Navin Sep 08 '15 at 10:53
  • And the informations stores regarding that `where to lookup` ? – Suresh Atta Sep 08 '15 at 11:00
  • @sᴜʀᴇsʜᴀᴛᴛᴀ All the info is part of the class' bytecode. – Navin Sep 08 '15 at 11:10
  • 3
    The document you link to describe the logical procedure for deciding which method to invoke, but this is not how it happens at runtime (even if it sounds like that in the text). A call to a method through a reference of a *class type* does not involve a recursive search in the parent classes. Only an array lookup in the class vtable is needed to find the right method in that case, so that is very fast. A call to a method through a reference of an *interface type* is performed something like what you describe, but the result of the search is cached, so it is only done once. – Lii Sep 08 '15 at 11:49
  • 1
    @Lii Ah, didn't know that. I guess that's why method calls are not ridiculously slow in libraries with long inheritance chains. – Navin Sep 08 '15 at 15:39
  • 2
    Even if an implementation uses a recursive lookup, there is no reason why calling a `final` method should be faster than any other. When the lookup starts, it is not known whether the target method is `final`. When the lookup has found a match, the lookup procedure is at its end and discovering that the matching method is `final` won’t turn back the time spent looking up that method. – Holger Sep 11 '15 at 15:24
7

Neither.

Inheritance is a programming language concept, not a real action. When you investigate the compiled Child class, e.g. with javap, you won’t find any artifact related to the three methods of Parent. There will be the information that Child has the superclass Parent, but no mentioning of the inherited methods, neither as references nor as copies.

The fact that Child conceptionally inherits methods from Parent comes into play when you actually try to invoke one of them through a variable whose compile-time type is Child, like in your Test class. Then it is up to the compiler to find the inherited methods in order to compile the code containing the invocation correctly. It is also up to the compiler whether it searches the class hierarchy every time it resolves a target method of an invocation or whether it collects the existing methods in certain data structures to speed up subsequent lookups and which data structures it uses.

This process is more complicated than you might think. There may be multiple candidates among which the compiler has to select one and it may even fail due to ambiguity. The result of the process will be a decision about whether the invocation is valid and, in case it is valid, a single target method and its actual signature.

The compiled invocation will contain the name and signature of the target method and a reference to the compile time type of the reference on which it is invoked, i.e. Child. It will not contain the information that the actual method has been inherited from Parent. This is intentional. Whether Child declares the method itself, inherits it from Parent or overrides a method of Parent should not affect the code of the invoker Test nor the compatibility between compiled class files.


This implies that at runtime a class like Test may contain a reference, given by name and signature, to a method in Child not being stored in the class file of Child, in other words, the JVM is responsible as well, for making the concept of inheritance working. At the same time, it has to ensure that the concept of overriding works, when a method invocation is executed.

The way it implements this is also unspecified, leaving room for different strategies. Searching class hierarchies on every invocation would be legal, but lead to poor performance.

A common technique is a vtable. Associated with every class is a table (array) containing references to the available methods, be it declared or inherited. On initialization of a subclass, its table will start with a copy of the superclass’ table, having entries for new methods appended at the end and entries of overridden methods changed. At some time, the method invocation will be linked by finding the index of the vtable entry, appropriate to the specified name and signature. A typical strategy is to do the lookup on the first invocation. The instruction is then modified to refer to the index to avoid subsequent lookups. From then, subsequent executions consist of fetching the vtable for an object’s runtime class and getting the method reference from the table’s entry.

Considering that, you could say that at runtime, inheritance is typically implemented as some kind of reference—but wait.

Implementations like Oracle’s JVM are capable of doing hotspot optimizations in which the context of often executed code is considered. There might be, for example an inherited method which itself invokes methods which have been overridden in some subclasses. When the JVM finds out that this method is called very often on a single concrete subclass, it may create an optimized version for that particular case. Then, a copy of the method’s code will be the starting point for the subsequent code transformations, inlining code of the specific subclass, etc.

Since such sophisticated implementations will use references for non-optimized code while using optimized copies in other cases, an alternative to the initial answer answer could be:

Both.

Holger
  • 285,553
  • 42
  • 434
  • 765
3

Method bodies aren't copied in the undefined method body of a subclass. Instead, when you call

Child child1 = new Child();
child1.method1();

It will look through its hierarchy, going up a level every time it can't find an implementation. First it will check Child which has no implementation. One level above that there's Parent which does, so it will use that one.As correctly mentioned by @Dante above that this is achieved via the super() call in the constructor of the Child Class. This image might help you get a better picture : enter image description here

I think your confusion is somehow associated to the point of non inheritance of the private methods.So,I would like to address that as well

Why Private Members are not inherited ?

You could say that private members are not inherited, because nowhere can Child refer explicitly to value. I.e. any code like this.value can't be used within Child, nor can obj.value be used from some calling code (obviously). However, in another sense, you could say that value is inherited. If you consider that every instance of Child is also an instance of Parent, then that object must contain 'value' as defined in Parent. Even if the Child class knows nothing about it, a private member name value still exists within each and every instance of Child. So in this sense, you could say that value is "inherited" in Child.So without using the word "inheritance", just remember that child classes don't know about private member defined within parent classes. But also remember that those private members still exists within instances of the child class.

Note: The the JLS states (http://docs.oracle.com/javase/specs/jls/se5.0/html/classes.html#8.2):

Members of a class that are declared private are not inherited by subclasses of that class. Only members of a class that are declared protected or public are inherited by subclasses declared in a package other than the one in which the class is declared.

Naveen Goyal
  • 446
  • 1
  • 3
  • 12
1

Java does not make a copy of the methods.The methods that are inherited stay with the parent class only.

Now you must me wondering,How does child class get access to them?

The answer lies in understanding the super keyword.

The super keyword is used to refer to object of immediate parent class.The very first thing super does is initialize object of parent class.This means it is responsible for creating object of parent class and is used to refer to that object.

The super(); is implicitly the first statement inside constructor of child class,however you can do that explicitly also.

Now the important part:

If you have the following:

super();

not as your first statement inside child class constructor,then compile error is generated saying:

call to super must be first statement in constructor.

The reason is:

Because the child class is assumed to have the inherited methods,but do not possess a copy of them.

The inherited methods are basically with parent class,so it is important to create object of parent class first,so that whenever following is used

instance_of_child.method_of_parent();

The method will be actually invoked from object of parent class,which was already created by super(explicitly or implicitly used).

This is the reason why you can have child class constructor like:

Child()
{
 super();
 parent_method();
}

but not like:

Child()
{
 parent_method();
 super();
}

because parent_method(),that is the inherited method requires reference to object of parent class which is provided by super().

Sumeet
  • 8,086
  • 3
  • 25
  • 45
  • Is it possible to achieve overloading in multiple classes using inheritance? – Harshit Gupta Sep 10 '15 at 12:57
  • Suppose if i have a class Parent it has a method add(int i, int j) and i inherit the Parent class in Child class and define a method with name add(int i, int j, int k) then there will be two methods present with add name in the Child class one is by inheritance and other is by normal creation but both with different number of arguments. Then this will be a case of Overloading. Is it true? – Harshit Gupta Sep 10 '15 at 13:06
  • @HarshitGupta You are right. But you can have overloading without using inheritance also. – Sumeet Sep 10 '15 at 13:07
  • I know about that but what my point is Overloading is possible with inheritance. – Harshit Gupta Sep 10 '15 at 13:08
  • But there is one rule for overloading which is the methods must be in the same class and yet you are saying that java does not create copy of the non private methods in the child class. How both things are possible togther? – Harshit Gupta Sep 10 '15 at 13:11
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/89285/discussion-between-dante-and-harshit-gupta). – Sumeet Sep 10 '15 at 13:12
  • Sure i am ok with it. – Harshit Gupta Sep 10 '15 at 13:13
  • @HarshitGupta It was nice discussion.But I think you are still not satisfied. – Sumeet Sep 10 '15 at 13:59
  • Yes really don't want to say that but its true i am still looking for more. But I appreciate your contribution very much. Thanks – Harshit Gupta Sep 10 '15 at 14:59
  • @SumeetSingh what happens to data members/fields during inheritance in Java? Are they virtually copied into subclass or they are also accessed via super just like in case of methods (as you explained in answer). My comment can be a follow up to: [this question](http://programmers.stackexchange.com/questions/236060/inheritance-is-code-from-superclass-virtually-copied-to-subclass-or-is-it-r) – AnV Mar 31 '16 at 08:32