Infinite_Loop
Infinite_Loop

Reputation: 380

Understanding hierarchy in Java

I am super confused about inheritance and object creation and I am trying to understand what objects are fully constructed in the below example.

class example
{
   public static void main (String[] args)
   {
      System.out.println("starting...") ;

      A  localAinMain = new A() ;                              // object created
      B  localBinMain = new B() ;                              // object created
      C  localCinMain = new C() ;                              // object created

      System.out.println("...finishing") ;

      return ;
   }
}

class A
{
   // class fields
   protected static int objectNo   =     0   ;
   private   static C   staticCinA = new C() ;                 // object created

   // instance fields
   public final int serialNo = ++objectNo ;

   public A () { System.out.println("\tA.A[" + serialNo + "] - ctor\n") ; }

   static      { System.out.println("\tA      - static initializer\n") ; }
}

class B extends A
{
   // class fields
   private static B staticBinB = new B() ;                     // object created

   // instance fields
   private A  instanceAinB = new A() ;                         // object created

   public B () { System.out.println("\tB.B[" + serialNo + "] - ctor\n") ; }

   static      { System.out.println("\tB      - static initializer\n") ; }
}

class C extends B
{
   // class fields
   private static A staticAinC = new A() ;                     // object created

   // instance fields
   private B  instanceBinC = new B() ;                         // object created

   public C () { System.out.println("\tC.C[" + serialNo + "] - ctor\n") ; }

   static      { System.out.println("\tC      - static initializer\n") ; }
}

When I run this program, I get the below output

starting...
    A.A[1] - ctor

    A.A[2] - ctor

    B.B[1] - ctor

    B      - static initializer

    A.A[3] - ctor

    C      - static initializer

    A.A[4] - ctor

    A.A[5] - ctor

    B.B[4] - ctor

    A.A[6] - ctor

    A.A[7] - ctor

    B.B[6] - ctor

    C.C[4] - ctor

    A      - static initializer

    A.A[8] - ctor

    A.A[9] - ctor

    A.A[10] - ctor

    B.B[9] - ctor

    A.A[11] - ctor

    A.A[12] - ctor

    B.B[11] - ctor

    A.A[13] - ctor

    A.A[14] - ctor

    B.B[13] - ctor

    C.C[11] - ctor

...finishing

I am wondering if someone can explain the object creation order like C.C[11] and A.A[11] will be "localCinMain", but I am not understanding why so any help is appreciated

Upvotes: 0

Views: 129

Answers (3)

Sabareesh Kappagantu
Sabareesh Kappagantu

Reputation: 2587

Every derived class constructor calls the base class constructor before it executes itself.

Why? The job of the constructor is to initialize the object properly. The Derived class has access to only it's members but inherits the properties of the Base class. Calling the Base class constructor makes sure that the object is constructed correctly.

The order in which a constructor is called during execution is as follows,
1. The memory is allocated for the variables defined.
2. The variables with initialization values outside the constructor (Eg. int a = 10) are initialized.
3. The constructor is called. But the code in the constructor will be executed only after the Base class constructor is called (implicitly).

Now to give you a start to understand the output,

When in the main the program reaches the "A localAinMain = new A() ;" line, here's what happens.
1. The memory for the object of class A must be allocated.
2. 'ObjectNo' is allocated it's space and an object of class C is allocated it's space.
3. Next the initialization of ObjectNo happens and then the initialization of the Object of class C happens. Now within class C follow a similar approach to see how the space for an object is allocated and also how the constructors are called. Keep in mind that when the constructor for Class C is called, the constructors of A and then B have to be called because class C inherits from them.

I hope this clears up your question. Feel free to correct the answer or ask more into it, as I'm a learner too.

Upvotes: 1

Guy Bouallet
Guy Bouallet

Reputation: 2125

In Java, when a class is instantiated, the default constructors of its super-classes are systematically called. The complete hierarchy (going to Object class) is traversed. This is officially documented here:

If a subclass constructor invokes a constructor of its superclass, either explicitly or implicitly, you might think that there will be a whole chain of constructors called, all the way back to the constructor of Object. In fact, this is the case. It is called constructor chaining, and you need to be aware of it when there is a long line of class descent.

Upvotes: 1

Reinstate Monica
Reinstate Monica

Reputation: 2808

When you call the constructor of a subclass, the first call in that constructor always has to be a call to the super. If you do not explicitly put in a call to the constructor of the superclass, a call will implicitly be made.

Because this call to the super always happens before anything else, the order of the code executed is always super, then subclass.

A code example of an explicit call to the superclass:

public class B extends A {
    public B() {
        super();
        //Code for constructing B.
    }
}

If you try to place this call after some other code, your compiler will complain, because it's illegal.

Does this answer your question?

Upvotes: 1

Related Questions