Copy constructor for abstract class

2019-04-20 05:42发布

I have an abstract class named AClass. In the same package I have AnotherClass, in which I have an ArrayList of AClass objects. In the copy constructor of AnotherClass I need to make a duplicate of AClass objects inside the ArrayList.

The problem:

I cannot create a copy constructor in AClass because it is an abstract class and I cannot know the name of the class which will inherit by AClass. Actually, in this project, no object will inherit from this class, but this project will be used as a library by other projects which will provide a class child of AClass. Is there an error in my design or is there a solution to this problem?

Edit: here's some code:

public class AnotherClass{
    private ArrayList<AClass> list;
...
    /** Copy constructor
    */
    public AnotherClass(AnotherClass another){
        // copy all fields from "another"
        this.list = new ArrayList<AClass>();
        for(int i = 0; i < another.list.size(); i++){
            // Option 1: this.list.add(new AClass(another.list.get(i)));
            // problem: cannot instantiate AClass as it is abstract
            // Option 2: this.list.add(another.list.get(i).someKindOfClone());
            // problem? I'm thinking about it, seems to be what dasblinkenlight is suggesting below
        }
    }
...
}

1条回答
做个烂人
2楼-- · 2019-04-20 05:57

I cannot create a copy constructor in AClass because it is an abstract class and I cannot know the name of the class which will inherit by AClass

This is generally correct. However, since you have a list of AClass, you do not need to know the exact subtype: an abstract function that make a copy would be sufficient:

protected abstract AClass makeCopy();

This is similar to the clone() function of the java.lang.Object, except all subclasses must implement it, and the return type is required to be AClass.

Since each subclass knows its own type, they should have no problem implementing makeCopy() method. Here is how this would look in your code:

for (int i = 0 ; i < another.list.size() ; i++) {
    this.list.add(another.list.get(i).makeCopy());
}

Note: this design is known as the prototype pattern, sometimes informally called the "virtual constructor".

查看更多
登录 后发表回答