C# 使属性在满足条件时可见
本文关键字:条件 满足 属性 | 更新日期: 2023-09-27 17:56:12
我终于开始研究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 weapon = new Weapon();
weapon.WeaponType = WeaponType.Sword;
weapon.Block = 5;
在这种情况下,我应该看不到 Block 属性。
更进一步,我不想将武器和盔甲与角色分开实例化(我还有一个角色类)。
我的最终目标是做这样的事情:
Character character = new Character();
character.WeaponType = WeaponType.Sword;
character.WeaponType.Damage = 10;
或者类似的东西,我什至不确定我的结构是否正确,所以我愿意接受建议!谢谢!
在这里忘记继承并使用组合。例如,从基础开始:
公共枚举项质量{ 常见 罕见 罕见 史诗 传奇}
public class Item
{
public ItemQuality ItemQuality { get; set; }
// other things common to all items here
public List<IFeature> features { get; set; }
}
那么IFeature
是什么.首先,这是一个空接口:
public interface IFeature { }
但是现在让我们开始添加武器:
public interface IAttackWeapon : IFeature
{
int Damage { get; set; }
}
public interface IDefenceWeapon : IFeature
{
int Block { get; set; }
}
然后我们可以开始定义一些类:
public class Weapon : IAttackWeapon
{
public Damage { get; set }
}
public class Shield : IDefenceWeapon
{
public int Block { get; set; }
}
那么,我可以定义一些武器:
public static readonly Item ShortSword = new Item
{
ItemQuality = ItemQuality.Common,
Cost = 5,
Features = new List<IFeature>
{
new Weapon { Damage = 4 }
}
}
通过采用这种组合方法,如果我们说以后想要一把魔剑,我们不需要创建更多的类,更多的属性来隐藏等。我们也不会遇到"我的魔剑应该继承武器还是魔法物品"的问题。相反,我们会添加一个新功能,例如:
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 }
}
}
我不会选择这种方式,特别是如果你想保持良好的 OOP。
为什么不使用接口,例如一个 IAttacckable 和 IBlockable。盾牌将仅实现IB
可锁定接口,剑可锁定和IB可锁定,枪仅可锁定你会问武器物体是否可以阻止
if (currentWeapon is IBlockable)
{
var blockWeapon = currentWeapon as IBlockable;
blockWeapon.blockHorizontal();
blockWeapon.blockVertical();
}
根据 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;
如果你需要一种新型武器,你可以像我们对剑和盾所做的那样子类武器类(假设你想要弓)。例如,如果您需要其他攻击武器,如刀,则可以对剑进行子类。
public class Knife {
public int length {get; set;}
}