Java 使用 super 和 sub 进行克隆 类

Java cloning with super and sub classes

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

您在滥用 clone()。当您实现 Cloneable 时,所有实例化和字段复制都由 super 实现完成。您的 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 转换为另一个时,您 不是 更改实际对象,而是以不同的方式访问它。

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

相反,您可能想要启动对象而不是在 Truck.clone 中调用 super.clone():

    return new Vehicle(this.y);

super.clone() return Vehicle 类型的对象,而不是 Truck。 所以你应该在 Truck.

的构造函数中调用 super(x)
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; 
    }
}