我有两个简单的Java类,我试图更多地了解克隆以及如何在不同级别的类之间进行转换。这是超类车辆。
public class Vehicle implements Cloneable
{
public int x;
public Vehicle(int y) {
x = y;
}
@Override public Object clone() {
Object result = new Vehicle(this.x);
// Location "A"
return result;
}
}
这是卡车的子类
public class Truck extends Vehicle
{
private int y;
public Truck(int z) {
super(z);
y = z;
}
@Override public Object clone() {
Object result = super.clone();
System.out.println(result.getClass());
((Truck) result).y = this.y;
return result;
}
}
我正在尝试获取卡车的副本,同时使用超类克隆,但有不允许向下转发的问题。我不确定如何解决这个或错误的位置。
我想:卡车a =新卡车(1)和卡车b = a.clone()成为同一个对象。
super.clone()
返回Vehicle
类型的对象,而不是Truck
。所以你应该在super(x)
的构造函数中调用Truck
。
public class Truck extends Vehicle
{
private int y;
public Truck(int x, int y) {
super(x);
this.y = y;
}
@Override public Object clone() {
Object result = new Truck(this.x, this.y);
return result;
}
}
你在滥用clone()
。当您实现super
时,所有实例化和字段复制都由Cloneable
实现完成。您的Vehicle
实现应如下所示:
@Override
public Vehicle clone() {
try {
return (Vehicle)super.clone();
} catch (CloneNotSupportedException e) {
throw new AssertionError();
}
}
您可以选择在Truck
中覆盖它,如下所示:
@Override
public Truck clone() {
return (Truck)super.clone();
}
当您从一个类转换为另一个类时,您不会更改实际对象,而是以不同的方式访问它。
class A { public int x; }
class B extends A { public int y; }
A a = new A();
B aB = new B();
System.out.println(aB); // A@...
System.out.println(aB.y); // throws an error
当你调用super.clone()
时,它会创建一个Vehicle
实例,而Vehicle
实例则没有y
。
相反,你可能想要启动对象而不是在super.clone()
中调用Truck.clone
:
return new Vehicle(this.y);