I have a class, which has subclasses for which I would like to handle copying objects properly. The superclass, called Item, has a copy constructor and the subclasses also have their own. However, what I want to know is to how to make it the following will work.
Item class (simplified description)
constructor:
public Item(...) {
}
copy constructor:
public Item( Item template ) {
}
The subclasses are things like Weapon, Armor, Shield, etc.
What I want to do is to able to say:
Weapon weapon = new Item( weapon );
Where weapon is a Weapon and the proper copy constructor (belonging to the specific subclass) is called, returning a new Object of type Weapon, as opposed to just getting back a new Item with only the Item parts that belonged to weapon. What is the best and/or right way to do this?
Since your copy constructor will be interacting with subclasses only, you should have abstract method for your copy constructor in the parent class and then define your copy constructors in child classes
Firstly, the following line will never compile if Weapon is a subclass of Item.
Weapon weapon = new Item( weapon );
Instead of using a constructor, you can use a static copy() method in the Item class. Using the example below, each subclass must declare its own private copy constructor. These constructors are not visible to the outside world. Therefore, the only way to copy an Item is through Item#copy().
Item.java
public class Item {
public String name;
public Item(String name) {
this.name = name;
}
private Item(Item template){
this(template.name);
}
public static Item copy(Item template) {
try {
Class<? extends Item> clazz = template.getClass();
Constructor<? extends Item> constructor = clazz.getDeclaredConstructor(clazz);
constructor.setAccessible(true);
return constructor.newInstance(template);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
Weapon.java
public class Weapon extends Item {
double damage = 50.4;
public Weapon(String name, double weight) {
super(name);
this.damage = weight;
}
private Weapon(Weapon template) {
this(template.name, template.damage);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With