类型转换为更具体的类型

Héc*_*orn 1 java inheritance class

我有以下问题.假设我有以下两个类:骑自行车山地自行车.在MountainBike的标题中我说:public class MountainBike extends Bicycle.MountainBike类添加了Bicycle中不存在的两个字段.因为我逐个添加属性(因为我正在使用数据库),所以没有构造函数,而是一个函数,它设置给定String标识符和值的属性.我知道可能没有设置所有属性并且可能为null,但这对我来说没问题.

现在问题如下.在某一点上我知道它是什么类型的自行车,它是其中一个领域.我想做的是以下内容:一旦我知道这个Bicycle对象实际上是MountainBike,我想将其转换为MountainBike:MountainBike mb = (MountainBike) bicycle但是这会导致运行时java.lang.ClassCastException:Bicycle不能施放到MountainBike.

我确信这是可能的(不使用构造函数将整个自行车作为参数).我怎样才能做到这一点?

谢谢!

埃克托

Bri*_*ian 6

就像Jon Skeet在他的评论中所说的那样,如果它不是一个MountainBike并且只是一个简单的话你就不能施展它Bicycle.你可以做的是创建一个构造函数MountainBike这需要Bicycle作为一个参数:

public MountainBike(Bicycle bicycle) {
    // Copy bicycle's properties
}
Run Code Online (Sandbox Code Playgroud)

而是称之为:

MountainBike mb = new MountainBike(Bicycle bicycle);
Run Code Online (Sandbox Code Playgroud)

如果MountainBike由于某种原因无法修改类,还可以创建static工厂方法:

public class MountainBikeFactory {

    public static MountainBike createMountainBike(Bicycle bicycle) {
        MountainBike mb = new MountainBike();
        // Copy bicycle's properties
        return mb;
    }
}
Run Code Online (Sandbox Code Playgroud)

并称之为:

MountainBike mb = MountainBikeFactory.create(bicycle);
Run Code Online (Sandbox Code Playgroud)

编辑:在查看您发布的信息作为对问题的评论之后,看起来您可以尝试构建器模式.构建器将包含所有属性作为变量(是的,它将长达100多个变量)并且当您从文件中发现属性时,在构建器上设置它们.然后,最后,当您调用构建器的build()方法时,让它解析要创建哪种类型的自行车,并使用多态来处理您创建的自行车组的属性组.

例如:

public class BikeBuilder {
    private String model;
    private String wheelSize;
    private String shocks;
    private String racingHandleBarType;

    // returns "this" so you can chain calls, common in builders, not necessary
    public BikeBuilder setModel(String model) {
        this.model = model;
        return this;
    }

    // Other setters

    public Bike build() {
        Bike bike;
        // Determine which kind of bike it is and create it
        if (shocks != null) {
            bike = new MountainBike();
            handleMountainBike((MountainBike) bike);
        } else if (racingHandleBarType != null) {
            bike = new RacingBike();
            handleRacingBike((RacingBike) bike);
        } else {
            bike = new Bike();
        }
        handleCommonAttributes(bike);
        return bike;
    }

    // All bikes have these attributes
    private void handleCommonAttributes(Bike bike) {
        bike.setModel(model);
        bike.setWheelSize(wheelSize);
    }

    private void handleMountainBike(MountainBike bike) {
        bike.setShocks(shocks);
    }

    private void handleRacingBike(RacingBike bike) {
        bike.setRacingHandleBarType(racingHandleBarType);
    }
}
Run Code Online (Sandbox Code Playgroud)

这允许您动态构建自行车,并在文件而不是开头读取结束时确定其类型.它可以作为一种容器.如果您有多种扩展类型,Bike则可以为它们创建新方法.这至少可以让你开始.