我是一名新的Java开发人员,我在java中继承概念遇到了一些困难来定义我的类......
在一方面,我有一个名为 Vehicle 的通用类,它定义了数十年的属性(使用其getter / setter)。我有一个 Vehicle1 类扩展车辆类。
另一方面,我有一个名为 VehicleFactory 的通用classe,它定义了一个这样的静态方法:
public class VehicleFactory {
protected static Vehicle makeResult() {
Vehicle result = new Vehicle();
result.setCode("1");
result.setNumber("2");
// other setters methods
return result;
}
问题是我想用自己的makeResult方法创建一个 Vehicle1Factory 类,该方法使用其父类的makeResult方法。但我没有做到这一点(这里的目标是优化,因为Vehicle1具有Vehicle classe的所有通用属性,但有一些额外的属性)。
我试着写的是这样的:
public class Vehicle1Factory extends VehicleFactory {
protected static Vehicle1 makeResult() {
Vehicle1 result = new Vehicle1();
result = (Vehicle1) VehicleFactory.makeResult();
// I want to reuse the makeResult of its parent class to define
// its own makeResult method
}
}
但是当我这样做时,Java告诉我有一个ClassCastException并且我不能在这里使用演员......
那种情况有解决方案吗?
答案 0 :(得分:1)
创建Something
的实例后,它永远不会成为其他内容的实例。由于VehicleFactory.makeResult
创建了Vehicle
个实例,因此无法将其转换为Vehicle1
。
您必须为此创建new Vehicle1
。
解决方案可以是将您要重用的代码移动到实用程序方法,例如:
class Vehicle { }
class Bike extends Vehicle { }
class VehicleFactory {
static Vehicle create() {
Vehicle vehicle = new Vehicle();
initialize(vehicle);
return vehicle;
}
private static void initialize(Vehicle vehicle) {
result.setCode("1");
result.setNumber("2");
// ...
}
}
class BikeFactory {
static Bike create() {
Bike bike = new Bike();
VehicleFactory.initialize(bike);
return bike;
}
}
答案 1 :(得分:0)
ClassCastException
是因为您正在尝试将Vehicle
投放到Vehicle1
;
为什么你不能这样做?因为如果对象类型在Vehicle1
引用类型下为Vehicle
,您可以将其强制转换。
public class Vehicle1Factory extends VehicleFactory {
protected static Vehicle1 makeResult() {
// Change reference type to Vehicle
Vehicle result = VehicleFactory.makeResult();
// I want to reuse the makeResult of its parent class to define
// its own makeResult method
}
}
让我们试着澄清一下铸造的所有黑暗点。
Super sub1 = new Sub(); // No casting required!
Super super1 = new Super();
Sub sub2 = new Sub();
sub2 = (Sub) sub1; // Casting required, because reference type is Super, but it's okay because real object under the reference is Sub();
sub2 = (Sub) super1(); // ClassCastException because real object is of Super type
最后一行的演员告诉编译器不要担心,我是一个优秀的程序员,我知道我在做什么,超类引用引用的对象实际上是在运行时的Sub类。所以没有编译时错误。但是在运行时,这会失败,因为实际对象不是Sub
,而是Super
。
答案 2 :(得分:0)
由于已经回答了ClassCastException问题。我想就如何设置抽象提出一些意见。
1)在抽象类中定义抽象工厂概念通常是个好主意。
2)我没有看到“保护”和“静止”在一起的意义。除非您的类仅由同一包中的子类和类使用。
3)扩展具体类并仅使用其静态方法没有意义。将静态和继承混合在一起通常是一种不好的做法。
无论如何,这里是带有更清晰抽象定义的示例代码:
public class Vehicle {
private int code = 0;
private int number = 0;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
}
public class Vehicle1 extends Vehicle {
private String engine = null;
public String getEngine() {
return engine;
}
public void setEngine(String engine) {
this.engine = engine;
}
}
public abstract class AbstractVehicleFactory<T extends Vehicle> {
protected T makeVehicle() {
T result = create();
result.setCode(11);
result.setNumber(24);
return result;
}
protected abstract T create();
}
public class VehicleFactory extends AbstractVehicleFactory<Vehicle> {
public static Vehicle makeResult(){
return new VehicleFactory().makeVehicle();
}
@Override
protected Vehicle makeVehicle() {
Vehicle result = super.makeVehicle();
return result;
}
@Override
protected Vehicle create(){
return new Vehicle();
}
}
public class Vehicle1Factory extends AbstractVehicleFactory<Vehicle1> {
public static Vehicle1 makeResult(){
return new Vehicle1Factory().makeVehicle();
}
@Override
protected Vehicle1 makeVehicle() {
Vehicle1 result = super.makeVehicle();
result.setEngine("V8");
return result;
}
@Override
protected Vehicle1 create(){
return new Vehicle1();
}
}
答案 3 :(得分:0)
问题是一个向下倾斜的问题。认为您在Vehicle中有X和Y参数,但在Vehicle1中添加了Z参数。 Vehicle1将其中的所有3个作为其车辆的女儿。当您将其投射到Vehicle时,它只是隐藏了Z的引用,但是当您将Vehicle转换为Vehicle1时,由于未为Vehicle1初始化Z变量,因此会发生转换问题。
在方法中初始化vehicle1并设置参数。如
public class
Vehicle1Factory extends VehicleFactory {
protected static Vehicle1 makeResult(){
Vehicle1 result = new Vehicle1();
Vehicle veh = (Vehicle1) VehicleFactory.makeResult();
result.setCode(veh.getCode);
result.setNumber(veh.getNumber);
return result;
}
}