具有多态性和继承性的类设计

时间:2011-08-07 17:35:52

标签: c# inheritance polymorphism

我目前有以下内容:

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()
        {

        }

    }

考虑到这一点,我创建的任何类都将继承此基础,并且还继承了类字段。例如,一个类可能是战士;另一个可能是Battlemage等。

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

编辑:

我忘了提及所有派生词都是单身,我将Class的名称改为“CharacterClass”,以避免混淆。

4 个答案:

答案 0 :(得分:2)

我认为你不是指哪个类,而是所有游戏对象类?在这种情况下,如果所有游戏对象确实需要这些属性,那么它可能是一个很好的设计。

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

强制初始化这些字段的一种可能性是在基类中提供非默认构造函数,要求子类将init值作为参数传递给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;
}

答案 1 :(得分:1)

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

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

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

答案 2 :(得分:0)

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

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

我在你的基类中看到一些属性,如MajorSkills。我看到你将从这个基类继承一个类“BattleImage”但是,我不认为图像具有技能。 我会创建更具体的基类,并且只有在存在 Is A 关系的情况下才从这些基类继承。

答案 3 :(得分:0)

我认为保留抽象字段并不是特别错误,如果它们对所有派生类都是通用的,尽管我建议使用Anders给出的解决方案。

我特别不喜欢的部分是IDictionary<int, Character> characterList;

我将假设您的Character内部有一个CharacterClass引用,以便您可以随时访问详细信息,并且看起来,您将创建一个循环CharacterCharacterClass。看起来你正在让CharacterClass承担太多责任。我将负责将特定CharacterClass的所有字符保存在别处。