jeudi 6 juin 2019

Instantiating objects whose subclass will depend on user input

Please excuse the silly questions, I'm fairly new to Java and OOP and I'm trying to follow the Design patterns (avoiding ifs, switches, etc) but I'm having a hard time doing so.

So, I'm building a weapon vendor for a 'game' project of my own. This vendor has a list of objects. These objects are all different instances of the Weapon Superclass (e.g. Sword, Spear, Axe, etc).

When a user tries to buy a weapon, the vendor will show the weapon list and the user selects one by inputting its list index.

I'm now facing two problems:

1) How can I make an instance of an object whose subclass will depend on user input? 2) How can I invoke the right constructor, passing the same parameters of the weapon bought to the new object to be instantiated? I'm trying to do this in the most polymorphic way possible, avoiding ifs and switch statements.

So far, what I tried was making an Interface (iWeapon). Then, based on that interface I made a Factory that receives the type of a weapon (String) and returns a new instance of a weapon with the corresponding subclass.

This allowed me to instantiate a 'generic' weapon using the data type of the interface. However, I don't know if this is the optimal way of achieving this. Also, I don't know how to initialize the attributes of the new instance with the same values of the recently bought weapon, in a polymorphic way.

I tried creating a method 'getAttributesFromOtherWeapon' on all my weapon subclasses, that receives an object with the same types and simply copies these values. The problem I'm facing now is that the iWeapon type object I instantiate doesn't have this method, and if I include it on the interface I get an error on my subclasses saying that 'Class must either be declared abstract or implement abstract method '

My vendor code does something like this:

Weapon weaponToBuy = (Weapon) weaponList.get(weaponChosenIndex);
iWeapon newWeapon = weaponFactory.getWeapon(weaponToBuy.type);
newWeapon.getAttributesFromOtherWeapon(weaponToBuy);

However, since newWeapon is an iWeapon I needed to declare getAttributesFromOtherWeapon on its interface, which looks like this:

public interface iWeapon {


    void getAttributesFromOtherWeapon(iWeapon iWeapon);


}

And now, in every Weapon subclass where I try to implement this method I'm require to pass an iWeapon instead of the corresponding Subclass type (Sword, Spear, etc.). Problem is that in my iWeapon interface I didn't define all the attributes corresponding to a Weapon (or any Weapon subclass) since I understand they'd be defined as constants.

I think there's probably an out of the box solution to this that I'm not seeing due to me being a noob on Java. Any help will be thoroughly appreciated

Aucun commentaire:

Enregistrer un commentaire