C# 重载导致代码膨胀

C# 重载导致代码膨胀,c#,overloading,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, Drag

我试图发展我对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)
第一个呼叫另两个,直到有人死。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)
public static void StartFight(Warror warrior, Enemy enemy)
public static string YouAttack(Warror warrior, Enemy enemy)
public static string EnemyAttack(Enemy enemy, Warror warrior)
但这会产生大量的膨胀。尤其是随着目标战士数量的增加(半人马、恶魔、矮人等)

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

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

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

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

此处可以找到一些使用示例:

在你的例子中,让我们假设
兽人
扩展
战士
职业,让我们假设
地精
侏儒
扩展
敌人
职业。那么您的方法将如下所示:

public static void StartFight(Orc orcWarrior, Goblin goblinEnemy)
public static void StartFight(Warror warrior, Enemy enemy)
public static string YouAttack(Warror warrior, Enemy enemy)
public static string EnemyAttack(Enemy enemy, Warror warrior)
您可以传递任何扩展
敌人
战士
类的对象


这个继承树只是一个例子,正如其他人所提到的,您可以(也应该)根据自己的需要设计它,或多或少地抽象化。

要实现良好的抽象,我认为您需要阅读许多教程。。。但你可以从简单的事情开始:

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...");
        }
    }
}
公共接口单元
{
字符串名称{get;}
int HP{get;set;}
int装甲{get;}
int损坏{get;}
}
公共级地精:IUnit
{
公共字符串名称{get;}=“Goblin”;
公共整数HP{get;set;}=80;
公共装甲=>3;
公众伤害=>8;
}
公共职业骑士:尤尼特
{
公共字符串名称{get;}=“Knight”;
公共int HP{get;set;}=120;
公共装甲=>5;
公众伤害=>12;
}
公共阶级斗争体系
{
public void ProcessAttack(IUnit攻击者、IUnit目标)
{
Console.WriteLine(攻击者.Name+“正在攻击”+目标.Name);
int-damage=Math.Max(0,攻击者.damage-target.Armor);
target.HP-=伤害;

如果(目标HP< P>)你可能会考虑完全不同的方法:

定义一个结构或类来保存生物的属性和技能等级:生物名称、力量、敏捷性、剑技能、射箭技能、火球技能等等

定义一个单独的Attack()函数,可能调用子函数,如bowatch(技能等级、距离、箭头类型等)或Fireball(技能等级、距离等)


这可以通过为两边传递数组,并有一个“圆”来实现或者根据每个生物的反射或主动技能选择攻击顺序。

查看抽象类或更好的接口。它们可以帮助您准确地回答问题。您需要熟悉的搜索词包括“接口”、“继承”、“多态性”以及可能的“泛型”。另外,请阅读有关继承和虚拟方法的内容。处理此问题的常见方法是,使用不同单位类继承的超类(如“Fighter”)。您可以使用“Fighter”声明方法,然后可以传入Fighter的任何子类。您需要实现“used”的方法/属性在超类中,但你可以在子类中重写它们。你可以使用接口实现同样的效果。谢谢你所有的posiitive引申。我有一个怪物类,兽人、地精和龙都是从这个类派生的,所以我想我可能错过了一个使用继承的技巧。接口听起来很有希望,所以我将尝试找到一些关于它的资源。What是OOP的第三个“支柱”?@UweKeim封装当时孩子们叫它什么D@TadijaBagarić这很有帮助。谢谢。请注意,C#不支持多重(类)继承,因此在大多数情况下是可行的。想想“is-a”与“has-a”的对比吧当决定继承时。如果战斗能力可以放在一个单独的接口中,那么你不需要龙和兽人都继承相同的基类(这可能不是正确的基础,因为假定龙来自爬行动物物种,兽人是哺乳动物,它们可能有不同的基类,但仍然实现了
IAttackable
IFighter
接口)。这看起来不错,但我想——就像你说的那样——我需要找到一些关于接口的教程(?)@丰富:接口、抽象类、多态性和与游戏相关的设计模式。