Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the order of the Constructors in this Java Code?

Tags:

java

Here is the code, I defined two class named Father and Son, and create them in the main function:

public class Test {
    public static void main(String[] args) {
        Father father = new Son();
    }
}

class Father {
    private String name = "father";
    public Father() {
        who();
        tell(name);
    }
    public void who() {
        System.out.println("this is father");
    }
    public void tell(String name) {
        System.out.println("this is " + name);
    }
}

class Son extends Father {
    private String name = "son";
    public Son() {
        who();
        tell(name);
    }
    public void who() {
        System.out.println("this is son");
    }
    public void tell(String name) {
        System.out.println("this is " + name);
    }
}

and I got the output like this:

this is son
this is father
this is son
this is son

But I can not understand how this happened? Anyone can tell me why?

like image 722
ZRJ Avatar asked Mar 28 '12 09:03

ZRJ


2 Answers

  1. Let's start with the constructor of Son.

    public Son() {
        super(); // implied
        who();
        tell(name);
    }
    
  2. Father's constructor is called.

    public Father() {
        who();
        tell(name);
    }
    
  3. Because who() is overridden by Son, the Son's version will be called, printing "this is son".

  4. tell() is also overridden but the value passed in is Father.name, printing "this is father".

  5. Finally, the who() and tell(name) calls inside Son's constructor will be made printing "this is son" and "this is son" respectively.

like image 131
adarshr Avatar answered Oct 31 '22 09:10

adarshr


Here is what gets called:

new Son()
=>  
  Son._init
   =>  first every constructor calls super()
      Father._init
         Object._init
         who()  => is overridden, so prints "son"
         tell(name) => name is private, so cannot be overridden => "father"
   who()  => "son"
   tell(name)  => "son"   

Lessons to learn:

  • private fields and methods are private. Cannot be overridden.
  • Do not call methods from constructors that can be overridden. This can call methods on half-initialized class state (not happening in your case, though).
like image 25
Thilo Avatar answered Oct 31 '22 08:10

Thilo