何时用作投射物体?

时间:2013-05-25 16:18:58

标签: c# object polymorphism

我有点困惑,我正确地接近这个。假设我有一个滚动游戏,玩家可以击败怪物并收集物品,这里是我的玩家类的一些 :( c#)

    public string Name { get; set; }
    public double life { get; set; }
    public double power { get; set; }
    public Swords weapon { get; set; } // their Held weapon
    private List<Items> items; //Represents their backpack
    private Monster monster; //The monster they are currently facing.

    public Player(string name)
    {
        this.Name = name;
        life = 1000;
        power = 10;
        weapon = new Swords("Fists", 100, 1); //The power of the weapon. Can only punch at the start
        items = new List<Items>();
    }

    public void addItem(Items i)
    {
        items.Add(i);
    }

然后看看我在播放器类中使用的这种方法:

public void equiptSword() //
    {
        Swords tempSword;
        foreach (Items i in items)
        { 
            if (i is Swords)
            {
                tempSword = i as Swords;
                tempSword.equiptItem(this); 
            }
        }
    }

正如你所看到的,我有一个名为items的超级/基类,所有内容都来源于此。当玩家击败怪物时,他们获得了一把剑,我将其添加到物品清单(他们的背包)中。基类没有equiptItem()的虚方法,只有剑有这种方法。因此,我不能只键入类型items[5].equiptItem()。这意味着我必须使用if语句检查我是否是一把剑,如果是,则将其作为一把剑施放,然后装备它。但是有一些关于这一点的事情让我觉得我正在接近它,当然,我可以在基类Items中添加一个虚拟方法,但是我再次不希望所有项目都可以选择装备。

对不起,如果我在散步。

您怎么看?我正确接近这个吗?

1 个答案:

答案 0 :(得分:1)

我认为你走在正确的轨道上。

我同意你不想在Item添加一大堆不相关的内容。

我认为你可以提出一些可以简化代码的广泛接口。

例如,您可以拥有IEquippable接口,该接口具有Equip()方法。然后任何可装备的物品都会实施IEquippable

您可以使用其他界面以类似的方式表示其他内容,例如IConsumableIPortable

然后在您的代码中,您可以执行以下操作:

IEquippable equippable = item as IEquippable;

if (equippable != null)
    equippable.Equip(); /// Etc

使用Linq,您可以编写如下内容:

foreach (var equippableItem in inventoryItems.OfType<IEquippable>())
{
    equippableItem.Equip();
}

但是,您应尽可能保留强类型集合 - 但当然,库存本质上是异构集合。

另请注意,使用接口来表示这些概念可让您拥有实现多个概念的项目,例如IConsumableIPortable的药水。

将执行此操作的逻辑放入可以隐藏它的单独类中可能是个好主意;例如,一个处理装备的Equipper类。

但有一件事 - 我不明白为什么你必须通过在袋子里循环装备剑。我原本以为你会有一套物品(让我们称之为Loot)掉落在怪物身上,你会更喜欢这样:

void handleLoot(Loot loot)
{
    // Get first sword dropped, or null if none.
    var sword = Loot.Items.OfType<Sword>().FirstOrDefault();

    if (sword != null) // Sword implements IEquippable so we can:
        sword.Equip(); // just equip it.
}