- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我想制作一个库存/设备系统来与我的元素系统交互。我的项目系统是一个基于共享属性的继承类系统。
我将类型存储在枚举中,并为项目赋予枚举值。
我的继承结构:
Item {
Equippable {
Armor {Chest, Head}
Weapon {Melee, Ranged}
}
}
我让每个子类型在其父类中定义一个枚举变量,因此 Chest 将在显式基类构造函数调用中使用该类型定义 armorTypes 枚举。
例如
public enum armorTypes {Chest, Helmet}
public class Armor : Equippable
{
armorTypes armorType;
public Armor(armorTypes at) : base(equippableTypes.Armor)
{
armorType = at;
}
}
public class Chest : Armor
{
int defense = 10;
public Chest() : base(armorTypes.Chest) {}
}
public class Helmet : Armor
{
int defense = 5;
public Helmet() : base(armorTypes.Helmet) {}
}
在我的库存类中,我有这些项目的空白版本。
Inventory{
public Chest chestSlot;
public Helmet helmetSlot;
public Melee meleeSlot;
public Ranged rangedSlot;
}
我想根据属性比较两个插槽中的对象。
void Compare(Item item)
{
switch((item as Armor).armorType)
{
case armorTypes.Chest :
Console.WriteLine((item as Chest).defense + " or " + chestSlot.defense);
break;
case armorTypes.Helmet :
Console.WriteLine((item as Helmet).defense + " or " + helmetSlot.defense);
break;
}
}
但是,当我使用 as 关键字转换它时,不知何故我失去了我的实例?
此外,由于我需要访问 item.armorType,我无法封装 Armor,可以吗?
最佳答案
这就是我实现它的方式。首先让基类定义基本的比较方法:
abstract class Item
{
// these methods define base comparison operations;
// by default, items are not comparable;
public virtual bool CanCompareWith(Item item)
{
return false;
}
// since we don't know all possible item properties,
// this method hasn't implementation
public abstract void CompareWith(Item item);
}
接下来,我们必须定义一些默认设备。盔甲:
abstract class Equippable : Item {}
abstract class Armor : Equippable
{
// every armor has a Defence property
public abstract int Defence { get; }
// the base comparison logic of two armors
public override void CompareWith(Item item)
{
Console.WriteLine("{0} or {1}", ((Armor)item).Defence, this.Defence);
}
}
class Chest : Armor
{
// if you want for chests to be comared with chests only:
public override bool CanCompareWith(Item item)
{
return item is Chest;
}
public override int Defence
{
get { return 10; }
}
}
class Helmet : Armor
{
public override bool CanCompareWith(Item item)
{
return item is Helmet;
}
public override int Defence
{
get { return 5; }
}
}
武器:
abstract class Weapon : Equippable
{
// every weapon has Attack property
public abstract int Attack { get; }
// the base comparison logc of two weapons
public override void CompareWith(Item item)
{
Console.WriteLine("{0} or {1}", ((Weapon)item).Attack, this.Attack);
}
}
class Melee : Weapon
{
public override bool CanCompareWith(Item item)
{
return item is Melee;
}
public override int Attack
{
get { return 20; }
}
}
class Ranged : Weapon
{
public override bool CanCompareWith(Item item)
{
return item is Ranged;
}
public override int Attack
{
get { return 25; }
}
}
请注意,这里没有任何枚举。这是因为类型本身(例如,Chest
、Helmet
等)定义了具体元素所属的位置。枚举在这里只是多余的。
这是 list :
class Inventory
{
// this is inventory storage;
// collection allows the storage to be extended later, or be displayed at once
// (e.g., some ShowAllInventory method)
private readonly List<Item> inventoryItems;
public Inventory()
{
inventoryItems = new List<Item>
{
// some predefined inventory slots with default inventory items
new Chest(),
new Helmet(),
new Melee(),
new Ranged()
};
}
// these properties are required, if you want to access predefined
// inventory slots in strongly-typed manner; they are NOT required for comparison
public Chest ChestSlot
{
get { return (Chest)inventoryItems[0]; }
set { inventoryItems[0] = value; }
}
public Helmet HelmetSlot
{
get { return (Helmet)inventoryItems[1]; }
set { inventoryItems[1] = value; }
}
public Melee MeleeSlot
{
get { return (Melee)inventoryItems[2]; }
set { inventoryItems[2] = value; }
}
public Ranged RangedSlot
{
get { return (Ranged)inventoryItems[3]; }
set { inventoryItems[3] = value; }
}
// The comparison.
public void Compare(Item newItem)
{
foreach (var item in inventoryItems)
{
if (item.CanCompareWith(newItem))
{
item.CompareWith(newItem);
}
}
}
}
请注意,内部库存使用集合来存储其项目。这允许对项目执行批处理操作(如比较,在 Compare
方法中实现)。
现在,让我们定义一些新类型的元素并测试我们的库存:
class SuperHelmet : Helmet
{
public override int Defence
{
get { return 50; }
}
}
class SuperMelee : Melee
{
public override int Attack
{
get { return 200; }
}
}
测试:
var inventory = new Inventory();
var superHelmet = new SuperHelmet();
var superMeele = new SuperMelee();
inventory.Compare(superHelmet);
inventory.Compare(superMeele);
关于c# - 使用父类(super class)输入在泛型方法中访问的子类属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18926597/
我想了解 Ruby 方法 methods() 是如何工作的。 我尝试使用“ruby 方法”在 Google 上搜索,但这不是我需要的。 我也看过 ruby-doc.org,但我没有找到这种方法。
Test 方法 对指定的字符串执行一个正则表达式搜索,并返回一个 Boolean 值指示是否找到匹配的模式。 object.Test(string) 参数 object 必选项。总是一个
Replace 方法 替换在正则表达式查找中找到的文本。 object.Replace(string1, string2) 参数 object 必选项。总是一个 RegExp 对象的名称。
Raise 方法 生成运行时错误 object.Raise(number, source, description, helpfile, helpcontext) 参数 object 应为
Execute 方法 对指定的字符串执行正则表达式搜索。 object.Execute(string) 参数 object 必选项。总是一个 RegExp 对象的名称。 string
Clear 方法 清除 Err 对象的所有属性设置。 object.Clear object 应为 Err 对象的名称。 说明 在错误处理后,使用 Clear 显式地清除 Err 对象。此
CopyFile 方法 将一个或多个文件从某位置复制到另一位置。 object.CopyFile source, destination[, overwrite] 参数 object 必选
Copy 方法 将指定的文件或文件夹从某位置复制到另一位置。 object.Copy destination[, overwrite] 参数 object 必选项。应为 File 或 F
Close 方法 关闭打开的 TextStream 文件。 object.Close object 应为 TextStream 对象的名称。 说明 下面例子举例说明如何使用 Close 方
BuildPath 方法 向现有路径后添加名称。 object.BuildPath(path, name) 参数 object 必选项。应为 FileSystemObject 对象的名称
GetFolder 方法 返回与指定的路径中某文件夹相应的 Folder 对象。 object.GetFolder(folderspec) 参数 object 必选项。应为 FileSy
GetFileName 方法 返回指定路径(不是指定驱动器路径部分)的最后一个文件或文件夹。 object.GetFileName(pathspec) 参数 object 必选项。应为
GetFile 方法 返回与指定路径中某文件相应的 File 对象。 object.GetFile(filespec) 参数 object 必选项。应为 FileSystemObject
GetExtensionName 方法 返回字符串,该字符串包含路径最后一个组成部分的扩展名。 object.GetExtensionName(path) 参数 object 必选项。应
GetDriveName 方法 返回包含指定路径中驱动器名的字符串。 object.GetDriveName(path) 参数 object 必选项。应为 FileSystemObjec
GetDrive 方法 返回与指定的路径中驱动器相对应的 Drive 对象。 object.GetDrive drivespec 参数 object 必选项。应为 FileSystemO
GetBaseName 方法 返回字符串,其中包含文件的基本名 (不带扩展名), 或者提供的路径说明中的文件夹。 object.GetBaseName(path) 参数 object 必
GetAbsolutePathName 方法 从提供的指定路径中返回完整且含义明确的路径。 object.GetAbsolutePathName(pathspec) 参数 object
FolderExists 方法 如果指定的文件夹存在,则返回 True;否则返回 False。 object.FolderExists(folderspec) 参数 object 必选项
FileExists 方法 如果指定的文件存在返回 True;否则返回 False。 object.FileExists(filespec) 参数 object 必选项。应为 FileS
我是一名优秀的程序员,十分优秀!