运行下边的一段代码,观察输出情况,注意总结父类与子类之间构造方法的调用关系修改Parent构造方法的代码,

显式调用GrandParent的另一个构造函数,注意这句调用代码是否是第一句。

 

代码如下:

class Grandparent 
{


    public Grandparent()
     {

            System.out.println("GrandParent Created.");
    
}


    public Grandparent(String string) 
    {

            System.out.println("GrandParent Created.String:" + string);
    
    }

}



class Parent1 extends Grandparent
{

                                                                                                          
    public Parent1()
     {

            super("Hello.Grandparent.");

            System.out.println("Parent Created");
    
       // super("Hello.Grandparent.");

      }

}



class Child1 extends Parent1 
{


    public Child1()
     {
    
        System.out.println("Child Created");

      }

}



public class TestInherits 
{


    public static void main(String args[])
     {

            Child1 c = new Child1();
    
  }

}

程序的运行截图:

程序结果分析:在类的继承过程中,父类的构造函数也会被子类所继承,当子类创建对象是,会首先调用弗雷德构造函数,随后在调用自身的构造函数。值得注意的是当在子类中显示的调用父类的另一个构造函数是,应该用Super调用,而且,通过 super 调用基类构造方法,必须是子类构造方法中的第一个语句。子类的对象在创建时会先调用父类的构造函数,在调用自身的构造函数,反过来则不行,因为构造函数是用来给类的对象进行初始化的,父类的定义的public和protected函数和变量都会自动被继承到子类中,如果父类不初始化,这些定义在父类的函数和变量不能在子类中使用?

其实,不仅先调用父类的构造方法,在调用父类的构造方法之前,还先初始化了父类的静态变量和静态块
完整的初始化顺序是:

父类静态变量
父类静态块

子类静态变量
子类静态块

父类非静态变量
父类非静态块

父类构造函数

子类非静态变量
子类非静态块

子类构造函数