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

现在的问题如下。在给定的时间点,我知道它是哪种类型的自行车,它是其中之一。我想做的是:我一知道这个Bicycle对象实际上是一个MountainBike,就想将它强制转换为MountainBike:MountainBike mb = (MountainBike) bicycle,但是这会导致运行时java.lang.ClassCastException:自行车不能投向MountainBike。

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

谢谢!

赫克托

最佳答案

就像乔恩·斯基特(Jon Skeet)在评论中说的那样,如果它不是MountainBike并且只是普通的Bicycle,则无法对其进行转换。您可以做的是在MountainBike中创建一个以Bicycle作为参数的构造函数:

public MountainBike(Bicycle bicycle) {
    // Copy bicycle's properties
}


并称之为:

MountainBike mb = new MountainBike(Bicycle bicycle);


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

public class MountainBikeFactory {

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


并称之为:

MountainBike mb = MountainBikeFactory.create(bicycle);


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

例如:

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);
    }
}


这样,您就可以动态构建自行车,并在读取文件的末尾而不是开始时确定其类型。它充当一种容器。如果您有多个扩展Bike的类型,则可以为其创建新方法。这至少会让您入门。

10-05 22:20