处理游戏中的单一继承
Coping with single inheritance in a game
我对 2d 游戏有一个简单的概念。想想最终幻想/D&D 设置。我在 C# 中工作,但它更像是一个一般的单继承 OO 问题。我只是假设有一种方案,您可以实现许多接口但只继承一个 class.
游戏中存在三种类型的实体:玩家、村民和敌人。澄清一下,可以有多个玩家(AI),因为有些人可能会加入派对。
对于操作:
玩家可以进行战斗和对话。村民只能使用对话。敌人只能战斗。
对于状态:
所有实体在地图上都有一个位置。
战斗人员始终具有当前健康状况、最大健康状况等。
对话实体总是有一些特定的问候语、对话选项等
玩家、村民和敌人将是我的具体 class。看来我想要 2 个界面:战斗和对话,处理所有的动作。到目前为止一切顺利——然而,这些实体以一种对单一继承有问题的方式共享状态。根据我的设计,我似乎想要
- 在地图上有位置的抽象实体class
- abstract classes AbstractCombatant 和其他 AbstractDialogue 都继承自 Entity。 AbstractCombatant,比如有生命值、装备等状态
这里的问题是 Player 想要继承 Combatant 和 Dialogue 抽象 classes。对于单一继承,我不能。如果可以的话,我会遇到来自实体 class 的钻石继承问题。即使我只是让我的具体 classes 继承 Entity,那也将是另一个多重继承问题。当然,如果我完全将 Entity 部分从等式中剔除,只是将实体分别映射到位置,我仍然会遇到 Player 从两个 classes.
继承的问题
我想不出不重复实现的单继承设计。为此场景设置 class/interface 层次结构的最佳方法是什么?
您的问题领域/业务领域中的每个概念(玩家、敌人、村民等)都有一个 class 是很自然的。当这些概念具有共同特征时,问题自然会出现。考虑这个例子:
class House : IHouse
{
public int StreetNumber { get; }
}
class Boat : IBoat
{
public double SpeedKnots { get; }
}
class HouseBoat : House, Boat // does not compile
{
}
解决此问题的最简单方法是使用聚合。
平衡
保留对所有基础概念的引用并实现适当的接口以提供所有必需的功能。
class HouseBoat : IHouse, IBoat // implementing both interfaces is ok
{
private House house;
private Boat boat;
int IHouse.StreetNumber { get { return this.house.StreetNumber; } }
double IBoat.SpeedKnots { get { return this.boat.SpeedKnots; } }
}
有偏见
从其中一个概念(更相似的那个)派生并为其他概念实现接口。
class HouseBoat : Boat, IHouse // is more like a Boat
{
private House house; // model for the house aspects
int IHouse.StreetNumber { get { return this.house.StreetNumber; } }
}
进一步阅读
这是一个很常见的问题,因为它自然而然地出现了,正如上面提到的,Java 和 C# 都不允许多重继承。一个简单的google query with the right search terms就可以提供丰富的material.
我对 2d 游戏有一个简单的概念。想想最终幻想/D&D 设置。我在 C# 中工作,但它更像是一个一般的单继承 OO 问题。我只是假设有一种方案,您可以实现许多接口但只继承一个 class.
游戏中存在三种类型的实体:玩家、村民和敌人。澄清一下,可以有多个玩家(AI),因为有些人可能会加入派对。
对于操作: 玩家可以进行战斗和对话。村民只能使用对话。敌人只能战斗。
对于状态: 所有实体在地图上都有一个位置。 战斗人员始终具有当前健康状况、最大健康状况等。 对话实体总是有一些特定的问候语、对话选项等
玩家、村民和敌人将是我的具体 class。看来我想要 2 个界面:战斗和对话,处理所有的动作。到目前为止一切顺利——然而,这些实体以一种对单一继承有问题的方式共享状态。根据我的设计,我似乎想要
- 在地图上有位置的抽象实体class
- abstract classes AbstractCombatant 和其他 AbstractDialogue 都继承自 Entity。 AbstractCombatant,比如有生命值、装备等状态
这里的问题是 Player 想要继承 Combatant 和 Dialogue 抽象 classes。对于单一继承,我不能。如果可以的话,我会遇到来自实体 class 的钻石继承问题。即使我只是让我的具体 classes 继承 Entity,那也将是另一个多重继承问题。当然,如果我完全将 Entity 部分从等式中剔除,只是将实体分别映射到位置,我仍然会遇到 Player 从两个 classes.
继承的问题我想不出不重复实现的单继承设计。为此场景设置 class/interface 层次结构的最佳方法是什么?
您的问题领域/业务领域中的每个概念(玩家、敌人、村民等)都有一个 class 是很自然的。当这些概念具有共同特征时,问题自然会出现。考虑这个例子:
class House : IHouse
{
public int StreetNumber { get; }
}
class Boat : IBoat
{
public double SpeedKnots { get; }
}
class HouseBoat : House, Boat // does not compile
{
}
解决此问题的最简单方法是使用聚合。
平衡
保留对所有基础概念的引用并实现适当的接口以提供所有必需的功能。
class HouseBoat : IHouse, IBoat // implementing both interfaces is ok
{
private House house;
private Boat boat;
int IHouse.StreetNumber { get { return this.house.StreetNumber; } }
double IBoat.SpeedKnots { get { return this.boat.SpeedKnots; } }
}
有偏见
从其中一个概念(更相似的那个)派生并为其他概念实现接口。
class HouseBoat : Boat, IHouse // is more like a Boat
{
private House house; // model for the house aspects
int IHouse.StreetNumber { get { return this.house.StreetNumber; } }
}
进一步阅读
这是一个很常见的问题,因为它自然而然地出现了,正如上面提到的,Java 和 C# 都不允许多重继承。一个简单的google query with the right search terms就可以提供丰富的material.