运行下边的一段代码,观察输出情况,注意总结父类与子类之间构造方法的调用关系修改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函数和变量都会自动被继承到子类中,如果父类不初始化,这些定义在父类的函数和变量不能在子类中使用?
其实,不仅先调用父类的构造方法,在调用父类的构造方法之前,还先初始化了父类的静态变量和静态块
完整的初始化顺序是:
父类静态变量
父类静态块
子类静态变量
子类静态块
父类非静态变量
父类非静态块
父类构造函数
子类非静态变量
子类非静态块
子类构造函数