我目前正在学习Java中的继承,我在理解它时遇到了很多麻烦,但是我无法理解的一个主要问题是为什么在以下示例中需要调用超类构造函数以及它是如何进行的救命?此示例正好来自Oracle的super(...)
方法教程。
public MountainBike(int startHeight,
int startCadence,
int startSpeed,
int startGear) {
super(startCadence, startSpeed, startGear);
seatHeight = startHeight;
}
我最初的想法是super(startCadence, startSpeed, startGear);
会缩短当前构造函数中的参数代码,它只会获取父类中传入的值并将其添加到子类(如这个):
public MountainBike(int startHeight) {
...
}
然而,因为我已经知道这是错的,并再一次让我想到了super(startCadence, startSpeed, startGear);
真正做了什么的问题。我会非常感谢某种形式的解释,所以像我这样的初学者实际上可以理解而不是给我这个定义。
答案 0 :(得分:4)
因为MountainBike
是(某些类)Bike
的子类,所以它应该可以在需要Bike
对象的任何上下文中使用。如果你没有在子代中调用父类的构造函数,那么就不能保证子对象被正确初始化以充当父类的实例。
我模糊地回忆一下,在Java中,如果你没有在子构造函数中对父的构造函数进行显式调用,则隐式调用父元素的默认构造函数(即没有参数)。在你的情况下,这还不够,因为要么没有默认的构造函数,要么你真的需要将给予子构造函数的额外参数传递给父的构造函数。
答案 1 :(得分:1)
我们假设您的班级MountainBike
继承自Bike
。单词super
是对类的父类的引用。
如果Bike
有一个如下所示的构造函数:
public Bike(int startCadence, int startSpeed, int startGear) {
cadence = startCadence;
speed = startSpeed;
gear = startGear;
}
然后是MountainBike
构造函数,如下所示:
public MountainBike(int startCadence, int startSpeed, int startGear, int startHeight) {
super(startCadence, startSpeed, startGear);
seatHeight = startHeight;
}
几乎相当于:
public MountainBike(int startCadence, int startSpeed, int startGear, int startHeight) {
super.cadence = startCadence;
super.speed = startSpeed;
super.gear = startGear;
seatHeight = startHeight;
}
除了前者,我们称之为super
构造函数更好。首先,它避免了重复代码。对于两个,它节省了两行。对于三,如果我需要在speed
上包含一些验证逻辑,我可以将它包含在Bike
构造函数中,而不需要在MountainBike
构造函数中复制该代码同样。
chepner的答案解释了为什么第二个版本可能有问题的其他一些原因。但是这个答案有助于解释对super
构造函数的调用正在做什么。