我有两个简单的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;
}
}
我正在尝试使用超类进行克隆时获得Truck的副本,但是不允许向下转换。我不太确定如何解决此问题或错误所在。
我希望拥有:Truck a = new Truck(1)和Truck b = a.clone()成为同一对象。
答案 0 :(得分:1)
您滥用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();
}
答案 1 :(得分:0)
当您从一个类转换为另一个类时,您不是在更改实际对象,而是以其他方式对其进行访问。
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);
答案 2 :(得分:-1)
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;
}
}