7

给定有限数量的种类不同的项目,是用堆叠的枚举和枚举构造函数来表示它们,还是对它们进行子类化更好?还是有更好的方法?

为了给你一些背景信息,在我的小型 RPG 程序中(讽刺的是,这应该很简单),一个角色在他或她的库存中有不同种类的物品。物品因种类、用途和效果而异。

例如,一个物品栏是一个名为 Gremlin 的法术卷轴,它可以调整实用属性。另一件物品可能是一把名为 Mort 的剑,用于战斗并造成伤害。

在我的 RPG 代码中,我现在尝试了两种表示库存项目的方法。一种方法是子类化(例如,InventoryItem -> Spell -> AdjustingAttributes;InventoryItem -> Weapon -> Sword)并在需要时实例化每个子类,并分配诸如 Gremlin 和 Mort 之类的名称之类的值。

另一种方法是堆叠枚举和枚举构造函数。例如,我为 itemCategory 和 itemSpellTypes 和 itemWeaponTypes 创建了枚举,而 InventoryItem 枚举是这样的:

public enum InventoryItem {
   GREMLIN(itemType.SPELL, itemSpellTypes.ATTRIBUTE, Attribute.UTILITY),
   MORT(itemType.WEAPON, itemWeaponTypes.SWORD, 30);

   InventoryItem(itemType typeOfItem, itemSpellTypes spellType, Attribute attAdjusted) {
   // snip, enum logic here
   }
   InventoryItem(itemType typeOfItem, itemWeaponTypes weaponType, int dmg) {
   // snip, enum logic here 
   }
   // and so on, for all the permutations of items. 

}

有没有比这两种方法更好的 Java 编程实践?或者如果这些是唯一的方法,那么两者中哪一个更好?提前感谢您的建议。

4

3 回答 3

8

如果仅保存静态数据且逻辑极少(最好根本没有逻辑),则枚举很好。如果您的对象根据它们的种类而具有不同的行为,那么将它们实现为子类通常是一个好主意。

正如其他人所提到的,您很可能会为您的对象添加属性,而这些属性对所有类型都没有意义。例如。颜色属性对武器有意义,但对法术无效。在这种情况下,武器和法术不应该在同一个枚举中。

于 2010-04-21T07:33:44.187 回答
6

In the context you describe I would consider using a class hierarchy as opposed to enum definitions and supplementing this hierarchy with interfaces; e.g.

/**
 * Root of class hierarchy.
 */
public interface InventoryItem {
}

/**
 * Additional "parallel" interface implemented by some (but not all)
 * InventoryItems and other non-inventory items.
 */
public interface Usable {
  void use();
}

/**
 * A Spell is in InventoryItem and is also Usable.
 */
public abstract class Spell implements InventoryItem, Usable {
}

public class Gremlin extends Spell {
}

/**
 * A Door is *not* an InventoryItem but can be used.
 */
public class Door implements Usable {
}

The main advantage of this approach is that it allows you to treat a given object in different contexts (as InventoryItems or as a list of Usables). The other reason I would steer clear away from enums is that you're likely to define behaviour on your items (e.g. spell.cast(Person)) and this doesn't sit well in enums IMHO.

于 2010-04-21T07:44:39.947 回答
6

如果您想向项目添加新属性,则将它们作为子类实现可能会更容易。这样,如果一组项目获得一个新属性,它将传播到所有子类。

例如,如果所有种类都Weapon获得了特定的权重,您只需将该属性添加到该类。然后,此属性将传播到子类。

对于本质上更静态的其他事物,因此可以直接分配类型,枚举是好的。我在这里自由思考,所以我想 aWeapon可以DamageType分配给它:

public abstract class Weapon {

public enum DamageType {

 CUT,
 SMASH,
 PIERCE;
}

private DamageType damageType;
于 2010-04-21T07:35:42.473 回答