Java 继承迫使我在调用 super() 时做我不想做的事情

问题描述 投票:0回答:3

我正在阅读 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.");
}

这不是我们想要的行为。

  1. 这是继承的常见缺点吗?
  2. 遇到这种情况你会做什么?
java inheritance
3个回答
4
投票

缺点是什么?

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 之类的对象。 我通常不太喜欢太多基于方面的解决方案,但可能是值得考虑的事情。


1
投票

答案:

  1. 这不是缺点。这是一个特点。说真的:-)

  2. 将 'System.out.println("A XXX has been created.")' 移至受保护方法并使用它代替 System.out.println 的静态调用。


0
投票

引用自https://dev.java/learn/inheritance/polymorphism

如果子类构造函数调用其超类的构造函数, 无论是显式的还是隐式的,你可能会认为会有一个 调用的整个构造函数链,一直回到 对象的构造函数。事实上,情况确实如此。它被称为 构造函数链,当有一个时你需要意识到它 阶级血统的长线。

© www.soinside.com 2019 - 2024. All rights reserved.