我目前有以下内容:
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”,以避免混淆。
答案 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类具有调用类的接口,这些类包含您的实现代码,例如技能类,属性类以及您稍后将添加的所有其他类。这样,您可以添加新类型的技能和属性,并且您还可以在运行时修改这些技能和属性。您不希望字符类包含所有可能的实现。对于你想要做的事情,你想要支持对象组合而不是继承。
答案 2 :(得分:0)
我认为这很有气味。这个代码味道甚至有一个名字:God - class。
IMO,创建一个“母亲”(或上帝)类并不是一个好主意,其中所有其他类都继承自。
我在你的基类中看到一些属性,如MajorSkills
。我看到你将从这个基类继承一个类“BattleImage
”但是,我不认为图像具有技能。
我会创建更具体的基类,并且只有在存在 Is A 关系的情况下才从这些基类继承。
答案 3 :(得分:0)
我认为保留抽象字段并不是特别错误,如果它们对所有派生类都是通用的,尽管我建议使用Anders给出的解决方案。
我特别不喜欢的部分是IDictionary<int, Character> characterList;
。
我将假设您的Character
内部有一个CharacterClass
引用,以便您可以随时访问详细信息,并且看起来,您将创建一个循环Character
和CharacterClass
。看起来你正在让CharacterClass承担太多责任。我将负责将特定CharacterClass的所有字符保存在别处。