C#和适当的继承方式

C#和适当的继承方式,c#,inheritance,logic,C#,Inheritance,Logic,我正在做一个小太空游戏。 那里将需要许多可以建造的建筑物。 我不认为我的继承观念是正确的或有用的,我正在寻找一种在建造一座建筑物之前检查资源的好方法。如果我想要15+个资源,我不想检查每个建筑的所有资源。 这是我到目前为止对建筑的想法。 如果有任何帮助,我将不胜感激 namespace Space_Colony.Buildings { class Building { String name = "undefined"; int energyNee

我正在做一个小太空游戏。 那里将需要许多可以建造的建筑物。 我不认为我的继承观念是正确的或有用的,我正在寻找一种在建造一座建筑物之前检查资源的好方法。如果我想要15+个资源,我不想检查每个建筑的所有资源。 这是我到目前为止对建筑的想法。 如果有任何帮助,我将不胜感激

namespace Space_Colony.Buildings
{
    class Building
    {
        String name = "undefined";
        int energyNeeded = 100000;
        int energyProduced = -100000;
        int buildTime = 100000;
    }

    class Solar_Panel_Weak : Building
    {
        String name = "Weak Solar Panel";
        int energyNeeded = 0;
        int energyProduced = 3;
        int buildTime = 20;

        int res_Needed_Wood = 10;
        int res_Needed_Iron = 10;
        int res_Needed_Sand = 10;
        int res_Needed_Electronics = 10;
    }

    class Landing_Field : Building
    {
        String name = "Landing Field";
        int energyNeeded = 0;
        int energyProduced = 0;
        int buildTime = 20;

        int res_Needed_Wood = 10;
        int res_Needed_Concrete = 10;
        int res_Needed_Color = 10;
    }
}```

在当前代码中,子类的属性与基类属性完全不同。您应该更改属性的访问修饰符,以便子类可以使用这些属性。您可能还希望Building类是抽象的,因此无法实例化它

abstract class Building
{
    protected String name = "undefined";
    protected int energyNeeded = 100000;
    protected int energyProduced = -100000;
    protected int buildTime = 100000;
}

class Solar_Panel_Weak : Building
{
    int res_Needed_Wood = 10;
    int res_Needed_Iron = 10;
    int res_Needed_Sand = 10;
    int res_Needed_Electronics = 10;

    public Solar_Panel_Weak()
    {
        name = "Weak Solar Panel";
        energyNeeded = 0;
        energyProduced = 3;
        buildTime = 20;
    }
}

在当前代码中,子类的属性与基类属性完全不同。您应该更改属性的访问修饰符,以便子类可以使用这些属性。您可能还希望Building类是抽象的,因此无法实例化它

abstract class Building
{
    protected String name = "undefined";
    protected int energyNeeded = 100000;
    protected int energyProduced = -100000;
    protected int buildTime = 100000;
}

class Solar_Panel_Weak : Building
{
    int res_Needed_Wood = 10;
    int res_Needed_Iron = 10;
    int res_Needed_Sand = 10;
    int res_Needed_Electronics = 10;

    public Solar_Panel_Weak()
    {
        name = "Weak Solar Panel";
        energyNeeded = 0;
        energyProduced = 3;
        buildTime = 20;
    }
}

@danielm为您的模型很好地说明了继承,但我担心您的子类可能会失控

假设你有一个
营地
类,负责建造你定义的建筑。例如,没有以有意义的方式映射每个建筑所需的资源,以生成通用解决方案

public class Settlement
{
    ...
    public void Build(Building building, Inventory inventory)
    {
        if (building is Solar_Panel_Weak spw)
        {
            // I've omitted validation for brevity
            inventory.UseResource("Wood", spw.res_Needed_Wood);
            inventory.UseResource("Iron", spw.res_Needed_Iron);
            inventory.UseResource("Sand", spw.res_Needed_Sand);
            inventory.UseResource("Electronics", spw.res_Needed_Electronics);
        }
        else if (building is Landing_Field lf)
        {
            // I've omitted validation for brevity
            inventory.UseResource("Wood", spw.res_Needed_Wood);
            inventory.UseResource("Concrete", spw.res_Needed_Concrete);
            inventory.UseResource("Color", spw.res_Needed_Color);
        }
        // So on...
    }
}
将有大量重复的代码,需要修改代码中的多个位置以添加新建筑

如果您决定让子类处理构建,则会出现类似的问题,因为处理所需资源的方式将要求每个子类实现
Build
方法

通过重组类以接受材质列表,例如:

public class Material
{
    public string Name { get; set; }
    public int QtyRequired { get; set; }
}

public abstract class Building
{
    public IEnumerable<Material> MaterialsRequired = new List<Material>();

    public string Name { get; set; }
    public int BuildTime { get; set; }
    public int EnergyNeeded { get; set; }
    public int EnergyProduced { get; set; }

    public Building(string name, int buildTime, int energyNeeded, int energyProduced)
    {
        Name = name;
        BuildTime = buildTime;
        EnergyNeeded = energyNeeded;
        EnergyProduced = energyProduced;
    }
}

public class SolarPanels : Building
{
    public SolarPanels() : base("Solar Panel", 20, 0, 3)
    {
        MaterialsRequired = new List<Material>
        {
            new Material { Name = "Wood", QtyRequired = 10 },
            new Material { Name = "Iron", QtyRequired = 10 },
            new Material { Name = "Sand", QtyRequired = 10 },
            new Material { Name = "Electronics", QtyRequired = 10 },
        };
    }
}

通过这种方法,负责建造建筑物的班级不必太费劲地思考建造建筑物的问题。我希望这能有所帮助。

@danielm为您的模型很好地说明了继承,但我担心您的子类可能会失控

假设你有一个
营地
类,负责建造你定义的建筑。例如,没有以有意义的方式映射每个建筑所需的资源,以生成通用解决方案

public class Settlement
{
    ...
    public void Build(Building building, Inventory inventory)
    {
        if (building is Solar_Panel_Weak spw)
        {
            // I've omitted validation for brevity
            inventory.UseResource("Wood", spw.res_Needed_Wood);
            inventory.UseResource("Iron", spw.res_Needed_Iron);
            inventory.UseResource("Sand", spw.res_Needed_Sand);
            inventory.UseResource("Electronics", spw.res_Needed_Electronics);
        }
        else if (building is Landing_Field lf)
        {
            // I've omitted validation for brevity
            inventory.UseResource("Wood", spw.res_Needed_Wood);
            inventory.UseResource("Concrete", spw.res_Needed_Concrete);
            inventory.UseResource("Color", spw.res_Needed_Color);
        }
        // So on...
    }
}
将有大量重复的代码,需要修改代码中的多个位置以添加新建筑

如果您决定让子类处理构建,则会出现类似的问题,因为处理所需资源的方式将要求每个子类实现
Build
方法

通过重组类以接受材质列表,例如:

public class Material
{
    public string Name { get; set; }
    public int QtyRequired { get; set; }
}

public abstract class Building
{
    public IEnumerable<Material> MaterialsRequired = new List<Material>();

    public string Name { get; set; }
    public int BuildTime { get; set; }
    public int EnergyNeeded { get; set; }
    public int EnergyProduced { get; set; }

    public Building(string name, int buildTime, int energyNeeded, int energyProduced)
    {
        Name = name;
        BuildTime = buildTime;
        EnergyNeeded = energyNeeded;
        EnergyProduced = energyProduced;
    }
}

public class SolarPanels : Building
{
    public SolarPanels() : base("Solar Panel", 20, 0, 3)
    {
        MaterialsRequired = new List<Material>
        {
            new Material { Name = "Wood", QtyRequired = 10 },
            new Material { Name = "Iron", QtyRequired = 10 },
            new Material { Name = "Sand", QtyRequired = 10 },
            new Material { Name = "Electronics", QtyRequired = 10 },
        };
    }
}
通过这种方法,负责建造建筑物的班级不必太费劲地思考建造建筑物的问题。我希望这有点帮助