我有以下现实设备的Enum常数:
HELMET,
CHESTPIECE,
BOOTS,
SWORD,
MACE,
HAMMER,
SHIELD,
BOW,
CROSSBOW,
STAFF
...;
我还有另一个名为Battle
的班级,该班级规定在特定的战斗中可以使用哪些装备。例如:
new Battle(Equipment.HAMMER, Equipment.SHIELD, EQUIPMENT.BOW);
这意味着只能使用Hammers,Shields或Bows。
现在我对此进行了扩展,并且需要子类别。例如:
new Battle(Equipment.SHIELD, Equipment.Weapons.values())
这相当于说:
new Battle(Equipment.SHIELD, Equipment.SWORD, Equipment.MACE, Equipment.HAMMER, ...)
等
这也意味着new Battle(Equipment.values())
应该产生每个枚举值
由于Enum
是最终的,我尝试了以下内容:
public interface Equipment { }
public enum MeleeWeapon implements Equipment
{
SWORD,
MACE,
HAMMER,
STAFF, ...;
}
public enum RangedWeapon implements Equipment
{
BOW, CROSSBOW;
}
...
但有了这个,我无法说Equipment.Weapon.values() // get all weapons, ranged and melee
。类之间没有任何继承关系的感觉,我也失去了界面中未定义的所有内容。在这里,它并不是一个好的解决方案。
我尝试过定期上课:
public abstract class Equipment
{
private static Set<Equipment> instances = new HashSet<>();
public static Set<Equipment> values()
{
return instances;
}
public Equipment()
{
instances.add(this);
}
}
public abstract class Weapon extends Equipment
{
private static Set<Weapon> instances = new HashSet<>();
public static Set<Weapon> values()
{
return instances;
}
public Weapon()
{
super() // explicit call
instances.add(this);
}
}
public class MeleeWeapon extends Weapon
{
private static Set<MeleeWeapon> instances = new HashSet<>();
public static final MeleeWeapon SWORD = new MeleeWeapon();
public static final MeleeWeapon MACE = new MeleeWeapon();
...
public static Set<MeleeWeapon> values()
{
return instances;
}
public MeleeWeapon()
{
super() // explicit call
instances.add(this);
}
}
不幸的是,有大量重复的代码,内存很重,而且public static Set<Weapon> values()
也会导致编译错误,因为它尝试使用不同的返回类型覆盖超类中的values()
。我能够用泛型(<? extends Weapon>
)解决这个问题,但它仍然是一个糟糕的解决方案。
这里的正确方法是什么?我需要继承我的枚举值,但我找不到如何做的方法。
答案 0 :(得分:3)
仍然保持枚举用法,可以将枚举的每个元素与它所属的组相关联,然后以专用方法返回过滤的元素组。
我们需要另一个 - 更小 - 枚举枚举要过滤的属性,例如:
public enum EquipmentType {
WEAPON, ARMOR, TOOL, CLOTHING;
}
枚举的元素与各自的组相关联:
public enum Equipment {
HELMET(ARMOR),
CHESTPIECE(ARMOR),
BOOTS(ARMOR, CLOTHING),
SWORD(WEAPON),
MACE(WEAPON),
HAMMER(WEAPON, TOOL),
SHIELD(ARMOR),
BOW(WEAPON),
CROSSBOW(WEAPON),
STAFF(WEAPON);
private final Set<EquipmentType> types;
Equipment(EquipmentType... eqTypes) {
this.types = Arrays.stream(eqTypes)
.collect(Collectors.toSet());
}
// common filtering method
private static List<Equipment> filterByType(EquipmentType type) {
return Arrays.stream(values())
.filter(eq -> eq.types.contains(type))
.collect(Collectors.toList());
}
// dedicated methods for each group of items
public static List<Equipment> getWeapons() {
return filterByType(WEAPON);
}
public static List<Equipment> getArmor() {
return filterByType(ARMOR);
}
}
这种方法仍然没有继承或更多的进化类型,我认为如果你想要更多的灵活性,最好避免使用枚举。