Java 克隆抽象对象

我想知道是否有任何方法可以执行以下操作。我有一个抽象类,以及它所有不同的子类,我想重写 clone 方法。我想在方法中做的所有事情就是从当前的方法创建一个新的。显然,我不能做以下事情,因为它是抽象的。有没有另一种方法可以做到这一点,因为为了简单的名称更改而覆盖每个子类中的克隆似乎毫无用处。ShapeShapetoString()Shape

public abstract class Shape {

    public Shape(String str) {
        // Create object from string representation
    }

    public Shape clone() {
        // Need new way to do this
        return new Shape(this.toString());   
    }

    public String toString() {
        // Correctly overriden toString()
    }
}

答案 1

您可以尝试使用反射:

public abstract class AClonable implements Cloneable{

private String val;

public AClonable(){

}

public AClonable(String s){
    val=s;
}

public String toString(){
    return val;
}

@Override
public AClonable clone(){
    try {
        System.out.println(getClass().getCanonicalName());
        AClonable b= getClass().getDeclaredConstructor(String.class).newInstance(val);

        return b;
    } catch (InstantiationException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IllegalArgumentException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (SecurityException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (NoSuchMethodException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return null;
}

}

在 clone() 方法中,您调用 getClass()。因为ACloneble的抽象,所以有调用将一切转到具体类。

   public class ClonebaleOne extends AClonable{

public ClonebaleOne(){
    super();
}

public ClonebaleOne(String s) {
    super(s);
    // TODO Auto-generated constructor stub
}

}

  public class ClonebaleTwo extends AClonable{

public ClonebaleTwo(){
    super();
}

public ClonebaleTwo(String s) {
    super(s);
    // TODO Auto-generated constructor stub
}

}

最后

   public static void main(String[] args){
    AClonable one = new ClonebaleOne("One");
    AClonable tow= new ClonebaleTwo("Two");
    AClonable clone = one.clone();
    System.out.println(clone.toString());
    clone = tow.clone();
    System.out.println(clone.toString());

}

输出:

  ClonebaleOne
  One
  ClonebaleTwo
  Two

但这更像是一种黑客行为,而不是一种解决方案。

[编辑]我的两个克隆比;)

[编辑]待定。clone() 的另一个含义可以是

 @Override
public AClonable clone(){
    try {
        ByteArrayOutputStream outByte = new ByteArrayOutputStream();
        ObjectOutputStream outObj = new ObjectOutputStream(outByte);
        ByteArrayInputStream inByte;
        ObjectInputStream inObject;
        outObj.writeObject(this);
        outObj.close();
        byte[] buffer = outByte.toByteArray();
        inByte = new ByteArrayInputStream(buffer);
        inObject = new ObjectInputStream(inByte);
        @SuppressWarnings("unchecked")
        Object deepcopy =  inObject.readObject();
        inObject.close();
        return (AClonable) deepcopy;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

当你的抽象类实现 Serialazable 时。在那里,您将对象写入光盘,并使用光盘中的值创建一个副本。


答案 2

您无法创建类的深度克隆,因为它们无法实例化。您所能做的就是通过使用或返回进行浅层克隆abstractObject.clone()this

@Override
public Object clone() throws CloneNotSupportedException {
    return super.clone();
}

@Override
public Object clone() throws CloneNotSupportedException {
    return this;
}

抽象类可以充当引用,并且不能具有实例,因此在这种情况下,浅层克隆可以工作

作为更好的方法,您可以声明为并要求子类定义它,如下所示clone()abstract

abstract class Shape {

    private String str;

    public Shape(String str) {
        this.str = str;
    }

    public abstract Shape clone();

    public String toString() {
        return str;
    }
}

class Circle extends Shape {

    public Circle(String str) {
        super(str);
    }

    @Override
    public Shape clone() {
        return new Circle("circle");
    }

}