我正在阅读 Oracle 网站上的官方 Java 教程,但我不喜欢在尝试继承时所看到的内容。
我创建了一个 Bicycle 类和一个扩展 Bicycle 的 MountainBike 类。 MountainBike 被迫从自己的构造函数中调用 Bicycle 的构造函数上的 super(),但这就是发生的情况:
A Bicycle has been created.
A Bicycle has been created.
A MountainBike has been created.
当课程看起来像这样(片段)时:
public Bicycle(int speed) {
this.speed = speed;
System.out.println("A Bicycle has been created.");
}
public MountainBike(int seatHeight, int speed) {
super(speed);
this.setSeatHeight(seatHeight);
System.out.println("A MountainBike has been created.");
}
这不是我们想要的行为。
缺点是什么?
MountainBike
类调用 Bicycle
构造函数,因此您将看到“自行车已创建”的输出。在您看到“山地自行车已创建”之前。输出。
如果您说您不想看到“自行车已创建”。创建
MountainBike
时的输出,您可能希望使用另一个知道要显示哪个输出的类来包装 Bicycle
或 MountainBike
的创建。 但基本上您在输出中看到的就是您期望看到的 MountainBike
is 也是 Bicycle
。
public class BikeWarehouse {
public Bicycle buildBicycle(int speed) {
Bicycle bicycle = new Bicycle(speed);
System.out.println("A Bicycle has been created.");
return bicycle;
}
public MountainBike buildMountainBike(int seatHeight, int speed) {
MountainBike mountainBike = new MountainBike(seatHeight, speed);
System.out.println("A MountainBike has been created.");
return mountainBike;
}
}
或者您可以将
toString()
方法放入 Bicycle
和 MountainBike
类中,然后当您创建其中一个时,您可以:
System.out.println("A " + bike + " has been created");
显然
toString()
的 Bicycle
将返回 "Bicycle"
,而 toString()
的 MountainBike
将返回 "MountainBike"
。
我也不太经常使用方面,但我相信可以做与上面类似的事情,而不会乱七八糟你的代码库(如果你发现上面的“乱七八糟”),但你也许可以登录创建你的使用 AspectJ 之类的对象。 我通常不太喜欢太多基于方面的解决方案,但可能是值得考虑的事情。
答案:
这不是缺点。这是一个特点。说真的:-)
将 'System.out.println("A XXX has been created.")' 移至受保护方法并使用它代替 System.out.println 的静态调用。
引用自https://dev.java/learn/inheritance/polymorphism
如果子类构造函数调用其超类的构造函数, 无论是显式的还是隐式的,你可能会认为会有一个 调用的整个构造函数链,一直回到 对象的构造函数。事实上,情况确实如此。它被称为 构造函数链,当有一个时你需要意识到它 阶级血统的长线。