使用上级和子类进行Java克隆

时间:2018-09-18 01:13:38

标签: java clone subclass superclass

我有两个简单的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()成为同一对象。

3 个答案:

答案 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; 
    }
}