【Java杂烩】在继承关系下构造函数执行时的顺序

得到的结论是:

先执行父类构造函数,再执行子类构造函数

 

父类:Animal.java

 

package extendsdemo;

public class Animal {
	public int age;
	public String name;
	public void eat(){
		System.out.println("动物具有吃东西的能力");
	}
	//如果父类已经存在了有参构造器方法,则系统不会隐式生存一个无参构造方法。
	//所以如果该类被继承,存在子类,那么必须显式写出一个无参构造方法,否则子类会报错。
	public Animal(){//父类的无参构造方法
		System.out.println("Animal类执行了");
	}
	public Animal(int a){//父类的含参构造方法
		System.out.println("父类的含参构造方法");
	}
}

 

 

 

 

 

子类:Dog.java 继承于Animal类

 

package extendsdemo;

public class Dog extends Animal{
	public Dog(){
		System.out.println("Dog类执行了");
	}
	
	@Override
	public void eat(){
		System.out.println("Dog具有吃骨头的能力");
	}
	
	public void supermethod(){//这里测试了super关键字
		super.eat();//如果子类重写了父类的方法,但是又想用父类的方法,就可以用super关键字
	}

}

 

 

 

 

 

 

子类:SmallDog.java 继承于Dog类

 

package extendsdemo;

public class SmallDog extends Dog{
	public SmallDog() {
		System.out.println("SmallDog类执行了");
	}
	public void eat(){
		System.out.println("SmallDog具有吃骨头的能力");
	}
	

}

 

 

 

 

 

 

测试类:Test.java

package extendsdemo;

public class Test {
	@SuppressWarnings("null")
	public static void main (String[] args){
		Dog dog=new Dog();
		Animal ani=new Dog();
		Animal ani2=new SmallDog();
		Dog dog2=new SmallDog();
		ani.eat();
		//dog.age=10;
		//dog.name="shijiake";
		//dog.eat();
		//dog.supermethod();//这里测试了super关键字
	
		
	}
}

 

运行的结果:

 

从上面的代码我们可以看到,我们这里分为三层的继承关系,Animal是Dog的父类,Dog是SmallDog的父类,我们分别实例化了四次。

第一次:Dog dog=new Dog()

我们可以看到结果是Animal类的构造函数先执行了,然后再执行Dog类的构造函数

第二次:Animal ani=new Dog()

这次我们可以看到,虽然我们是新建了一个Animal类的对象ani,但是我们引用的却是Dog类实例化对象的地址。所以执行顺序依然是首先Animal类的构造函数先执行了,然后再执行Dog类的构造函数

第三次:Animal ani2=new SmallDog()

这次的实习,我们可以看出,虽然SmallDog不属于Animal类的直接子类,但属于Animal类的子类Dog的子类,所以Animal类的对象是可以引用SmailDog实例化后所对应在内存的地址的。他的执行顺序也一样,首先实例化SmailDog类,必须先执行父类Dog的构造函数,又因为必须先执行Dog类的构造函数,所以也必须先执行Dog类的父类Animal类的构造函数,顺序是Animal->Dog->SmailDog

第四次:

第四次同上,主要证明执行顺序与左边新建什么类型的变量没有关系。

总结:

 

所以只要你实例化了某个类,而这个具有继承关系,他必然要先执行自己父类的构造函数,然后再执行自己的构造函数,倘若存在三层或多层以上的继承关系也一样。因为构造函数的执行顺序就是父类优先于子类。跟等式的左边其实没有太多的关系。

 

另外,在测试中,不得不提到一点的是。

平时我们新建一个类的时候,系统会默认为我们提供一个无参的构造函数。

 

但是如果一个类已经存在有参构造函数,则系统不会隐式生存一个无参构造函数。所以当这个类想被其他类继承的时候,程序员应该要为其添加一个无参构造器,否则子类继承了他是会出现报错的。

 

 

原因:父类没有无参构造函数,当子类需要实例化的时候,调用自己的无参构造函数时必然要先调用父类的无参构造函数,然而父类却没有,所以这里就矛盾了。

 

 

 

 

 

 

 

总结就到此为止啦~~

 

【Java异常学习笔记系列】Java异常体系以及异常的基本知识

 

 

欢迎关注我的博客,一起学习讨论

要转载,请附上原文链接,作者:SnailMann

 

可以关注我的私人github: https://github.com/SnailMann,欢迎watch ,star, fork

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值