Java继承中的“构造函数”

一、父类中没有定义任何构造方法

代码示例:

// 父类
class Vehicle{}

// 子类
class Car extends Vehicle{
	private String name;
	public Car(String name) {
		this.name = name;
	}
	@Override
	public String toString() {
		return "car name: " + this.name;
	}
}


public class VehicleTest {
	public static void main(String[] args) {		
		Vehicle v2 = new Car("A Car");
		System.out.println(v2);
	}
}

说明: 这里我们定义一个父类“Vehicle”,不包含任何的构造方法。实际上,编译器会自动给我们定义的“没有显示定义构造方法的类”去定义一个无参构造方法:

public Vehicle() {};

子类Car在创建实例 v2 时,会首先调用父类 Vehicle 的无参构造方法,创建一个 Vehicle 实例。第二步,调用子类 Car 的构造方法(含参),将上一步创建的 Vehicle 实例进行包装,成为一个 Car实例。第三步,执行 println(v2),此处会自动调用我们Car类中的 toString() 方法,这是由Object类决定的,这里写成 System.out.println(v2.toString())是一样的。

这里可以看到,我们定义一个类时,给一个类定义无参构造方法,或者不定义任何构造方法是相同的。


二、父类中只定义了有参构造方法

代码示例:

// 父类
class Vehicle{
	private String name;
//	public Vehicle() {};
	public Vehicle(String name){
		this.name = name;
	}
	@Override
	public String toString() {
		return "vehicle name: " + this.name;
	}
}

// 子类
class Car extends Vehicle{
	private String name;
	public Car(String name) {
		super(name);     # 调用父类有参构造
		this.name = name;
	}
	@Override
	public String toString() {
		return "car name: " + this.name;
	}
}


public class VehicleTest {
	public static void main(String[] args) {
		Vehicle v2 = new Car("A Car");
		System.out.println(v2);
	}
}

此处,我们可以看到子类中的构造方法中有一句 “super(name)”,这一句的功能是在显示的调用父类中的有参构造方法。如果我们注释掉这一行,IDE会报错:

是说“父类 Vehicle 中没有定义无参构造器,必须必须显式调用另一个构造函数”。出现这个错误的原因是因为,子类中的构造函数会默认尝试执行 super() 去调用父类的无参构造器 ,  但是我们的父类中没有无参构造方法,那么这里就无法继承父类的无参构造。

问题来了:为什么“一、父类中没有定义任何构造方法” 中也没有定义无参构造就没有错误呢?

因为如果一个Java类,我们不定义任何的构造方法,JVM就会自动帮我们构建一个无参构造方法(不可见)。但是,如果我们主动创建了一个构造方法,无论是有参还是无参构造方法,Java虚拟机就会认为用户创建了自己需要的构造方法,就不会再帮助我们创建任何构造方法。

知道了原因,就容易得出解决方法 (以下任意一种均可):

  1. 我们可以显示调用父类中的有参构造方法 super(name);
  2. 在父类中定义一个无参构造方法 public Vehicle() {};

三、完整代码示例

// 父类
class Vehicle{
	private String name;
	public Vehicle() {};
	public Vehicle(String name){
		this.name = name;
	}
	@Override
	public String toString() {
		return "vehicle name: " + this.name;
	}
}

// 子类
class Car extends Vehicle{
	private String name;
	public Car(String name) {
		super(name);
		this.name = name;
	}
	@Override
	public String toString() {
		return "car name: " + this.name;
	}
}


public class VehicleTest {

	public static void main(String[] args) {
		Vehicle v1 = new Vehicle("A Vehicle");
		System.out.println(v1);
		
		Vehicle v2 = new Car("A Car");
		System.out.println(v2.toString());
	}
}

可以通过设置断点,用Debug模式查看代码具体工作流程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值