Java在继承中构造器的调用顺序

   Java中子类继承父类时代码结构初始化以及调用的顺序:

   子类声明一个对象时,

    步骤1: 这时先调用的是基类的静态初始化块,然后是下一层的子类,一直到声明对象的类的静态初始化块。从这里就开始内存分配与初始化了。先有类才有对象。

    步骤2:new Wolf(5.6) 这句话先调用的是Wolf的构造函数,但是它并没有执行,而是去调用父类的构造函数,一层层往上,直到基类,这就像栈一样,先压进去,一会再一个个弹出来执行,在执行基类的构造函数之前,先必须执行非静态初始化块,执行完成后才会去执行构造函数,执行完后,会跳往刚才下一层的子类,调用刚才压进栈的构造函数,但是运行之前一样先运行非静态初始化块,包括在内存中分配空间以及赋值,直到压进栈的都弹出来执行完成后这个过程就结束了。

    需要注意的是子类可以通过在构造函数中使用super调用父类的相同类型的构造器,如果没有,那么默认的是调用父类的无参构造函数。

package cn.swpu;

class Creature
{
	
	{
		System.out.println("Creature的非静态初始化块");
	}
	static{
		System.out.println("我是最先运行的");
	}
	public Creature(){
		System.out.println("Creature无参数的构造器");
	}
	public Creature(String name)
	{
		this();
		System.out.println("Creature带有name参数的构造器,name参数:"+name);
	}
	}


class Animal extends Creature
{
	{
		System.out.println("Animal的非静态初始化块");
	}
	static
	{
		System.out.println("我是第二个运行的");
	}
	public Animal()
	{
		
	}
	public  Animal(String name)
	{
	    super(name);
	    System.out.println("Animal带一个参数的构造器,name参数:"+name);
	}
	public Animal(String name,int age)
	{
		this(name);
		System.out.println("Animal带两个参数的构造器,其age:"+age);
	}
	}

class Wolf extends  Animal
{
	{
		System.out.println("Wolf的非静态初始化块");
	}
	static
	{
		System.out.println("我是第三个运行的");
	}
	public Wolf()
	{
		super("灰太狼",3);
		System.out.println("Wolf的无参数的构造器");
	}
	public Wolf(double weight)
	{
		this();
		System.out.println("Wolf的带weight参数的构造器,weight参数:"+ weight);
	}
	}


public class Add {
public static void main(String[] args) {
	new Wolf(5.6);
	new Wolf(6.5);
}
}

输出的结果:

我是最先运行的
我是第二个运行的
我是第三个运行的
Creature的非静态初始化块
Creature无参数的构造器
Animal的非静态初始化块
Wolf的非静态初始化块
Wolf的带weight参数的构造器,weight参数:5.6



你可能感兴趣的:(Java)