【问题标题】:Class Design with Polymorphism and Inheritance具有多态性和继承性的类设计
【发布时间】:2023-04-06 00:12:01
【问题描述】:

我目前有以下:

public abstract class CharacterClass
    {

        public abstract Attribute FirstAttributeBonus { get; }
        public abstract Attribute SecondAttributeBonus { get; }

        protected Attribute[] attributeBonuses; //2 attribute bonuses, which add 10 to the attributes stored in the array.
        protected SKill[] majorSkills; //Major skills for class begin at 30.
        protected Skill[] minorSkills; //Minor skills for class begin at 15.

        protected IDictionary<int, Character> characterList; //List of characters who apply to this class specifically.

        public CharacterClass()
        {

        }

    }

考虑到我创建的任何类都将从这个基础继承,并且也继承类字段。例如,一个职业可能是战士;另一个可能是战斗法师等。

这是执行此类设计的正确方法,同时让派生构造函数初始化字段吗?还是在不继承这些字段的情况下编写类更好?

编辑:

我忘了说所有派生都是单例,我将 Class 的名称更改为“CharacterClass”,以避免混淆。

【问题讨论】:

  • 将一个类命名为“Class”势必会在未来造成重大混乱。
  • 请不要在标题前加上“C#”。这就是我们在Stack Overflow 上的标签。
  • @John Saunders 抱歉,我不会再这样做了。

标签: c# inheritance polymorphism


【解决方案1】:

我假设您不是指哪个类,而是所有游戏对象类?在这种情况下,如果 all 游戏对象真的需要这些属性,它可能是一个很好的设计。

抽象基类的作用是在那里收集公共代码以消除子类中的重复。如果所有游戏对象子类都需要这些字段,那么将它们放在基类中是正确的。如果不同的游戏对象子类将它们初始化为不同的值,则将初始化推迟到子类是正确的。

强制初始化这些字段的一种可能性是在基类中提供一个非默认构造函数,要求子类将初始化值作为参数传递给 ctor。

我假设您的意思是构造函数示例?改变你现有的

public CharacterClass()
{
}

变成类似的东西

public CharacterClass(Attribute[] attributeBonuses, 
  SKill[] majorSkills, Skill[] minorSkills)
{
  if(attributeBonuses == null || majorSkills == null || minorSkills == null)
    throw new ArgumentException("Null values are not allowed");

  this.attributeBonuses = attributeBonuses;
  this.majorSkills = majorSkills;
  this.minorSkills = minorSkills;
}

【讨论】:

  • 你能举个例子吗?
【解决方案2】:

您绝对需要掌握名为 Head Start Design Pattern 的书。您无需阅读整本书:它的第一章描述了您希望实现的设计模式。

基本上,您希望您的 Character 类具有调用类的接口,这些类包含您的实现代码,例如技能类、属性类以及您稍后将添加的所有其他类。这样,您可以添加新类型的技能和属性,并且还可以在运行时修改它们。您不希望字符类包含所有可能的实现。对于您正在尝试做的事情,您希望支持对象组合而不是继承。

花20分钟阅读第一章:http://oreilly.com/catalog/9780596007126/preview

【讨论】:

  • 好的,很酷。这完全取决于您将要重写多少次代码:) 编码快乐!
【解决方案3】:

我认为这是有气味的。这种代码气味甚至有一个名字:God - class

IMO,创建一个所有其他类都继承自的“母亲”(或上帝)类不是一个好主意。

我在您的基类中看到了一些属性,例如MajorSkills。我看到您将拥有一个类“BattleImage”,您将从该基类继承,但是,我不认为图像具有技能。 我会创建更具体的基类,并且仅在存在 Is A 关系时从这些基类继承。

【讨论】:

    【解决方案4】:

    如果所有派生类都通用受保护的抽象字段,我不认为有什么特别的问题,尽管我推荐Anders 给出的解决方案。

    我特别不喜欢的部分是IDictionary&lt;int, Character&gt; characterList;

    我将假设您的 Character 内部有一个 CharacterClass 引用,以便您可以在需要时访问详细信息,并且看起来,您将在 CharacterCharacterClass。看起来你让 CharacterClass 有太多的责任。我将把持有特定 CharacterClass 的所有 Characters 的责任转移到别处。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-02
      • 2022-11-03
      • 1970-01-01
      • 1970-01-01
      • 2011-07-24
      相关资源
      最近更新 更多