重载导致代码膨胀

时间:2017-11-04 18:50:55

标签: c# overloading

我正在努力发展我对OOP的理解,所以我创建了一个控制台冒险游戏。我有一个战斗类,基本上有3种方法:

public static void StartFight(Dragon dragonWarrior, Goblin goblinEnemy)
public static string YouAttack(Dragon dragonWarrior, Goblin goblinEnemy)
public static string EnemyAttack(Goblin goblinEnemy, Dragon dragonWarrior)

第一个打电话给另一个2,直到有人死亡。 YouAttack和EnemyAttack包括以下消息:

Console.WriteLine("{0} the dragon attacks {1} and has dealt {2} damage",
                  dragonWarrior.Name, goblinEnemy.Name, damageDone);

总之,让我们说我的3种方法共同占用了90行代码。

我的问题是这个。可以说,我有一个兽人。我可以轻松地复制和粘贴方法并重载它们:

public static void StartFight(Orc orcWarrior, Goblin goblinEnemy)

但这会产生很大的膨胀。特别是随着对象勇士数量的增加(半人马,恶魔,矮人等)

那么有没有办法传递一个对象和编译器找出传递了什么对象?如果有的话,有没有人知道一个好的教程?还有其他我可以研究的解决方案吗?

我知道这可能是一个垃圾问题,但我完全是自学成才。我没有任何代码的朋友或导师,所以每个问题都可能是一场斗争。 提前谢谢

3 个答案:

答案 0 :(得分:1)

您正在寻找的是继承(link)和多态(link) - 两者都是OOP的三大支柱之一(第三个是封装(link)

它们允许您使用您不知道确切类别的对象,但您仍然可以描述API或方法。

可以在此处找到一些示例用法:What is the real significance(use) of polymorphism

在您的示例中,我们可以说DragonOrc扩展Warrior类,然后让GoblinGnome扩展Enemy }类。然后你的方法看起来像这样:

public static void StartFight(Warror warrior, Enemy enemy)
public static string YouAttack(Warror warrior, Enemy enemy)
public static string EnemyAttack(Enemy enemy, Warror warrior)

您可以传递任何扩展EnemyWarrior类的对象。

这个继承树只是一个例子,正如其他人提到的那样,你可以(并且应该)根据你的需要设计它,或多或少是抽象的。

答案 1 :(得分:1)

为了做好抽象,我认为你需要经历许多教程......但你可以从简单的事情开始:

public interface IUnit
{
    string Name   { get; }
    int    HP     { get; set; }
    int    Armor  { get; }
    int    Damage { get; }
}

public class Goblin : IUnit
{
    public string Name { get; } = "Goblin";

    public int HP { get; set; } = 80;

    public int Armor  => 3;
    public int Damage => 8;
}

public class Knight : IUnit
{
    public string Name { get; } = "Knight";

    public int HP { get; set; } = 120;

    public int Armor  => 5;
    public int Damage => 12;
}

public class BattleSystem
{
    public void ProcessAttack (IUnit attacker, IUnit target)
    {
        Console.WriteLine (attacker.Name + " is attacking " + target.Name);

        int damage = Math.Max (0, attacker.Damage - target.Armor);

        target.HP -= damage;

        if (target.HP <= 0)
        {
            Console.WriteLine ("Enemy unit died...");
        }
    }
}

尽量避免使用像GoblinWarrior等具体类型。如果一个单位有第二个特殊武器,你需要实现抽象,允许任何单位拥有第二武器(但大多数当然只使用一种武器。)

Game programming patterns

答案 2 :(得分:1)

您可能会考虑采用完全不同的方法:

定义一个结构或类来保存生物的统计数据和技能等级:creature_name,strength,agility,sword_skill,archery_skill,fireball_skill,......

定义一个Attack()函数,可能调用BowAttack(skill_level,distance,arrow_type,...)或Fireball(skill_level,distance,......)等子函数

orc = new Creature("Orc A", 11, 0, 5, 1, 0, 0, 0, 0, ... ):
player = new Creature("Hero Bob", 20, 10, 11, 11, 1, 1, 1, 0, ... );

Fight( Creature& player, Creature& enemy)
while (player.health > 0 && enemy.health > 0)
{
player.Attack( enemy );
enemy.Attack( player );
}

通过为两边传递数组并且有一个&#34; round&#34;这可以更加花哨。或者通过他们的反射或主动技能选择每个生物的攻击顺序。