Java:简述父类与子类构造函数的调用次序

编程语言(Java基础) 专栏收录该内容
79 篇文章 8 订阅

Java:简述父类与子类构造函数的调用次序


一、题目(1):

下列代码在执行new Child(“test”)的时候,输出结果是什么呢?

class People {
	String name;
	
	public People() {
		System.out.println(1);
	}
	
	public People(String name) {
		System.out.println(2);
		this.name=name;
	}
}


class Child extends People {
	People father;
	
	public Child() {
		System.out.println(3);
	}
	
	public Child(String name) {
		System.out.println(4);
		this.name=name;
		
		father = new People("father:"+name);
	}
}

public class Test1 {
	public static void main(String[] args) {
		new Child("test");
	}
}

二、输出结果:

1
4
2

三、要点分析:

在Java中,子类的构造过程中必须调用其父类的构造函数,是因为有继承关系存在时,子类要把父类的内容继承下来。但如果父类有多个构造函数时,该如何选择调用呢?

第一个规则: 子类的构造过程中,必须调用其父类的构造方法。一个类,如果我们不写构造方法,那么编译器会帮我们加上一个默认的构造方法,就是没有参数的构造方法。但是如果我们自己写了构造方法,那么编译器就不会添加了。所以有时候当我们new一个子类对象的时候,必定调用了子类的构造方法。但是如果在子类构造方法中,我们并没有显示的调用基类的构造方法,如: super():,这样默认调用父类没有参数的构造方法。

第二个规则: 如果子类的构造方法中既没有显示的调用基类构造方法,而基类中又没有无参的构造方法,则编译出错。所以,通常我们需要显示的: super(参数列表),来调用父类有参数的构造函数,此时无参的构造函数就不会被调用。

四、题目(2):

下列代码执行后,输出结果是什么呢?

class Base {
	private String name="base";
	
	public Base() {
		tellName();
		printName();
	}
	
	public void tellName() {
		System.out.println("Base tell name:"+name);
	}
	
	public void printName() {
		System.out.println("Base print name:"+name);
	}
}

class Dervied extends Base {
	private String name="dervied";
	
	public Dervied() {
		tellName();
		printName();
	}
	
	public void tellName() {
		System.out.println("Dervied tell name:"+name);
	}
	
	public void printName() {
		System.out.println("Dervied print name:"+name);
	}
}

public class Test2 {
	public static void main(String[] args) {
		new Dervied();
	}	
}

五、输出结果:

Dervied tell name: null
Dervied print name: null
Dervied tell name: dervied
Dervied print name: dervied

六、要点分析:

第一步: 执行 new dervied时,因为 Dervied继承于父类Base,所以先调用父类构造中的方法 ,这时子类name域的值尚未初始化。但因为子类覆写了父类的方法,所以第一个调用的 telIName方法实际上调用子类的方法 Dervied. tellName方法。 tellName方法要打印name域(子类Dervied)的值,但是当前 Dervied对象中的name域还没有被初始化,所以打印出来的值为 null。printName方法执行与 tellName方法一致。

第二步: 调用子类 Dervied中的构造方法,因为这时子类的name域已经初化完,因此可以正常打印。

  • 3
    点赞
  • 0
    评论
  • 5
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值