我有以下问题。假设我有以下两个类:自行车山地自行车。在MountainBike的标题中我说:public class MountainBike extends Bicycle
。 MountainBike类添加了Bicycle中不存在的两个字段。因为我逐个添加属性(因为我正在使用数据库),所以没有构造函数,而是一个函数,它设置给定String标识符和值的属性。我知道有可能并非所有属性都已设置且可能为null,但这对我来说没问题。
现在问题如下。在某一点上我知道它是什么类型的自行车,它是其中一个领域。我想要做的是以下内容:一旦我知道这个Bicycle对象实际上是一个MountainBike,我想把它转换为MountainBike:MountainBike mb = (MountainBike) bicycle
,但是这会导致运行时java.lang。 ClassCastException:自行车无法转换为MountainBike。
我确信这是可能的(不使用构造函数将整个自行车作为参数)。我怎么能这样做?
谢谢!
埃克托
答案 0 :(得分:6)
就像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
的类型,则可以为它们创建新方法。这至少可以让你开始。
答案 1 :(得分:2)
如果您怀疑演员阵容可能会失败,请检查:
if (bike instanceof MountainBike) {
MountainBike mb = (MountainBike) bike
} else {
String msg = "Wrong bike, expected Mountainbike but was:" + bike.getClass();
System.out.println(msg);
throw new IllegalArgumentException(msg);
}
答案 2 :(得分:2)
你不能仅仅因为MountainBike延伸自行车而将自行车投入MountainBike。这是一个例子:
Bike bike = new MountainBike();
MountainBike mb = (MountainBike) bike; //works
Bike bike = new Bike();
MountainBike mb = (MountainBike) bike; //ClassCastException