2

I understand that downcasting may not be the best way to achieve my desires, but it at least indicates the kind of solutions I have running through my head. Any alternative suggestions are welcome.

Alright, so may as well dive into my code:

public void triggerItem(Item item) 
{
    if (item is Weapon) {
        equipWeapon(item);
    }       
}

public void equipWeapon(Weapon weapon) 
{

}

So I basically have an inventory set up, and of course the inventory will contain various types of items (weapons, armour, consumables, etc.) As you can see I have an Item class and then a Weapon class and a bunch of others which all inherit Item.

Now, I intend to call this function when the player clicks on an item in their inventory, then call different functions depending on the particular Type of Item.

But because equipWeapon() receives Weapon, it doesn't like it when I just pass it an Item.

I understand that I could change my code to equipWeapon(Item item), but the ultimate destination of the object requires a Weapon type and I'm reluctant to change that. It seems like a dirty solution and a step in the wrong direction, but feel free to correct me if I'm wrong.

Servy
  • 202,030
  • 26
  • 332
  • 449
K. West
  • 31
  • 3
  • This should be a big reg flag in your design. You need to code to interfaces and generalize – OldProgrammer Jun 22 '18 at 18:51
  • move *equip* method to *Item* class as an abstract method – Eser Jun 22 '18 at 18:52
  • Ah I expected to feel silly when the solutions started rolling in. I actually deleted the equip() method from my Item class earlier today when I got carried away restructuring. Bit of a brainfart moment I suppose. Many thanks to all of the people who have posted. – K. West Jun 22 '18 at 19:11

2 Answers2

2

Give your base class a method that causes it to be equipped, and implement it in the type-specific class that knows how to equip itself.

Example:

abstract class Item
{
    public abstract void Equip();
}

class Weapon
{
    public override void Equip()
    {
        equipWeapon(this);
    }
}

Then triggerItem becomes trivial:

public void triggerItem(Item item) 
{
    item.Equip();
}       

If you need to call equipWeapon on a different class (e.g. whatever class contains triggerItem) you can make the class part of the interface:

abstract class Item
{
    public abstract void Equip(Game context);
}

class Weapon
{
    public override void Equip(Game context)
    {
        context.equipWeapon(this);
    }
}

class Game
{
    public void triggerItem(Item item) 
    {
        item.Equip(this);
    }       
}
John Wu
  • 50,556
  • 8
  • 44
  • 80
-2

This solves it.

public void triggerItem(Item item) 
{
    if (item is Weapon) {
        equipWeapon((Weapon)item);
    }       
}

public void equipWeapon(Weapon weapon) 
{

}

What you do here is downcasting the Item to Weapon while passing to equipWeapon(Weapon weapon).

M. Azyoksul
  • 1,580
  • 2
  • 16
  • 43