我终于开始研究OOP原则,我目前正在制作一款简单的游戏。 情况如下: 我有一个名为Items的抽象类,它将项目的所有可能属性保存为属性,并将项目的质量保存为枚举:
public enum ItemQuality
{
Common,
Uncommon,
Rare,
Epic,
Legendary
}
public abstract class Items
{
public ItemQuality ItemQuality { get; set; }
public int Stamina { get; set; }
public int Strength { get; set; }
public int Agility { get; set; }
public int Intelligence { get; set; }
public int Damage { get; set; }
public int Block { get; set; }
public int Armor { get; set; }
}
我还有两个名为Weapon and Armor的类(它们继承了Items类),它们分别包含WeaponType和ArmorType,这两个类也都是枚举。
考虑以下场景:我制作了一个新的Sword类型的武器,我能够给它一个阻挡值,但它是一个它无法阻挡的武器。我想根据武器/护甲类型使不同的属性可见。
Weapon weapon = new Weapon();
weapon.WeaponType = WeaponType.Sword;
weapon.Block = 5;
在这种情况下,我不能看到Block属性。
为了更进一步,我不想与角色分开实例化武器和装甲(我也有角色类)。
我的最终目标是做这样的事情:
Character character = new Character();
character.WeaponType = WeaponType.Sword;
character.WeaponType.Damage = 10;
或类似的东西,我甚至不确定我的结构是否正确所以我愿意接受建议! 谢谢!
答案 0 :(得分:1)
我不会选择那种方式,特别是如果你想保持良好的OOP。
为什么不使用接口,例如一个IAttackable和IBlockable。一个盾牌只能实现IBlockable接口,一把剑是IAttackable和IBlockable,一只枪只能是IAttackable
你会问,武器对象是否可以阻挡
if (currentWeapon is IBlockable)
{
var blockWeapon = currentWeapon as IBlockable;
blockWeapon.blockHorizontal();
blockWeapon.blockVertical();
}
答案 1 :(得分:1)
Forget inheritance here and use composition. For example, start with the basics:
public enum ItemQuality { Common, Uncommon, Rare, Epic, Legendary }
public class Item
{
public ItemQuality ItemQuality { get; set; }
// other things common to all items here
public List<IFeature> features { get; set; }
}
So what is IFeature
. Well to start with, it's an empty interface:
public interface IFeature { }
But let's now start adding weapons:
public interface IAttackWeapon : IFeature
{
int Damage { get; set; }
}
public interface IDefenceWeapon : IFeature
{
int Block { get; set; }
}
We can then start defining some classes:
public class Weapon : IAttackWeapon
{
public Damage { get; set }
}
public class Shield : IDefenceWeapon
{
public int Block { get; set; }
}
So then, I might define some weapons:
public static readonly Item ShortSword = new Item
{
ItemQuality = ItemQuality.Common,
Cost = 5,
Features = new List<IFeature>
{
new Weapon { Damage = 4 }
}
}
By taking this composition approach, if we say want a magic sword at a later date, we do not need to create lots more classes, lots more properties to hide etc. Nor do we run into problems of "should my magic sword inherit from weapon or magic item?". Instead, we'd add a new feature, eg:
public static readonly Item MagicSword = new Item
{
ItemQuality = ItemQuality.Rare,
Cost = 5000,
Features = new List<IFeature>
{
new Weapon { Damage = 10 },
new MagicItem { Spell = Spells.TurnToFrog }
}
}
答案 2 :(得分:0)
根据OOP原则,将对象类型定义为枚举器是一种糟糕的设计。好的OOP会利用继承和可能的多态性。像那样:
public abstract class Weapon {
public int cost {get; set;}
}
public class Sword : Weapon {
public int damage {get; set;}
}
public class Shield : Weapon {
public int defense {get; set;}
}
现在你可以说:
Sword blade = new Sword();
blade.cost = 5;
blade.damage = 6;
Shield myShield = new Shield();
myShield.cost = 4;
myShield.defense = 7;
如果你需要一种新型武器,你可以像使用剑和盾一样继承武器类(让我们说,你想要弓)。 如果你需要像刀子这样的其他攻击武器,你可以继承Sword,例如。
public class Knife {
public int length {get; set;}
}