将对象转换为子类型? (沮丧)

Cast an object to child type? (Downcasting)

我知道沮丧可能不是实现我愿望的最佳方式,但它至少表明了我头脑中的解决方案运行。欢迎任何替代建议。

好的,不妨深入研究我的代码:

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

public void equipWeapon(Weapon weapon) 
{

}

所以我基本上设置了一个库存,当然库存将包含各种类型的物品(武器、盔甲、消耗品等)。如您所见,我有一个物品 class 然后一个武器 class 和一堆其他的都继承了物品。

现在,我打算在玩家点击物品栏中的物品时调用此函数,然后根据特定的物品类型调用不同的函数。

但是因为equipWeapon()收到了Weapon,所以当我只是给它一个Item的时候它不喜欢它。

我知道我可以将代码更改为 equipWeapon(Item item),但对象的最终目的地需要武器类型,我不愿意更改它。这似乎是一个肮脏的解决方案,是朝着错误方向迈出的一步,但如果我错了,请随时纠正我。

这就解决了。

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

public void equipWeapon(Weapon weapon) 
{

}

你在这里所做的是将 Item 向下转换为 Weapon,同时传递给 equipWeapon(Weapon weapon)

给你的基地 class 一个方法让它被装备,并在知道如何装备自己的特定类型 class 中实现它。

示例:

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

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

然后 triggerItem 变得微不足道:

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

如果您需要在不同的 class 上调用 equipWeapon(例如任何 class 包含 triggerItem),您可以将 class 设为接口的一部分:

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);
    }       
}