Java 我可以去掉这个开关和枚举吗?
我的印象是,通过某种方式利用多态性,这段代码可能会更干净,但我似乎找不到一种合适的方法来实现这一点。我试着使用访问者模式,但没有成功 具有开关的“英雄”类:Java 我可以去掉这个开关和枚举吗?,java,enums,switch-statement,Java,Enums,Switch Statement,我的印象是,通过某种方式利用多态性,这段代码可能会更干净,但我似乎找不到一种合适的方法来实现这一点。我试着使用访问者模式,但没有成功 具有开关的“英雄”类: public class Hero { private Equipment equipment = new Equipment(); // other fields public void equipArmor(Armor armor) { findCorrespondingArmorSlot(ar
public class Hero {
private Equipment equipment = new Equipment();
// other fields
public void equipArmor(Armor armor) {
findCorrespondingArmorSlot(armor).equipItem(armor);
}
private ItemSlot findCorrespondingArmorSlot(Armor armor) {
switch (armor.getArmorType()) {
case SHIELD:
return equipment.offHand;
case BODY:
return equipment.body;
case HEAD:
return equipment.head;
case GLOVES:
return equipment.hands;
case BOOTS:
return equipment.feet;
case BELT:
return equipment.waist;
case AMULET:
return equipment.neck;
case RING:
return equipment.finger;
case TRINKET:
return equipment.special;
}
throw new NullPointerException();
}
public Equipment getEquipment() {
return equipment;
}
// other methods
public class Equipment {
public ItemSlot mainHand = new ItemSlot();
public ItemSlot offHand = new ItemSlot();
public ItemSlot body = new ItemSlot();
public ItemSlot head = new ItemSlot();
public ItemSlot hands = new ItemSlot();
public ItemSlot feet = new ItemSlot();
public ItemSlot waist = new ItemSlot();
public ItemSlot neck = new ItemSlot();
public ItemSlot finger = new ItemSlot();
public ItemSlot special = new ItemSlot();
}
}
还有一些其他的东西:
public class ItemSlot {
private static final Miscellaneous EMPTY = new Miscellaneous();
private Item item = EMPTY;
public Item getItem() {
return item;
}
public void equipItem(Item item) {
unequipItem();
this.item = item;
}
public void unequipItem() {
if (!isEmpty()) {
item.addToInventory();
item = EMPTY;
}
}
public boolean isEmpty() {
return (item == EMPTY);
}
}
public abstract class Item {
// fields
public void addToInventory() {
// code
}
// other methods
}
public class Miscellaneous extends Item{}
public class Armor extends Item {
private ArmorType type;
public ArmorType getArmorType() {
return type;
}
//other methods
}
public enum ArmorType
{
SHIELD, BODY, HEAD, GLOVES, BOOTS, AMULET, RING, BELT, TRINKET;
}
设备类中的HashMap如何 像这样:
public HashMap<String, ItemSlot> itemSlots = new ItemSlots HashMap<String, ItemSlot>();
然后,您必须定义如下方法:
public ItemSlot getItemSlot(String item) {
return itemSlots.get(item);
}
最后,您的案例将类似于:
return equipment.getItemSlot(armor.getArmorType());
是的,你可以离开开关。请记住,枚举只是静态保证的单例。所以他们可以有方法。只需按照以下步骤进行操作:
public enum ArmorType {
SHIELD {
public ItemSlot getItemSlot(Equipment e) { return e.offHand; }
},
// ... repeat for all other armor types
TRINKET {
public ItemSlot getItemSlot(Equipment e) { return e.special; }
};
public abstract ItemSlot getItemSlot(Equipment e);
}
public enum ArmorType
{
SHIELD(){
public ItemSlot getArmorSlot(Equipment equipment){
return equipment.offHand;
}
},
...
public abstract ItemSlot getArmorSlot(Equipment equipment);
}
然后您可以简单地调用armorType.getItemSlot(equiment)代码>请尝试以下操作:
public enum ArmorType {
SHIELD {
public ItemSlot getItemSlot(Equipment e) { return e.offHand; }
},
// ... repeat for all other armor types
TRINKET {
public ItemSlot getItemSlot(Equipment e) { return e.special; }
};
public abstract ItemSlot getItemSlot(Equipment e);
}
public enum ArmorType
{
SHIELD(){
public ItemSlot getArmorSlot(Equipment equipment){
return equipment.offHand;
}
},
...
public abstract ItemSlot getArmorSlot(Equipment equipment);
}
然后打电话:
ItemSlot armorSlot = armor.getArmorType().getArmorSlot(equipment);
使用映射将解决此问题。我不会删除enum
。您可以遍历枚举
。使用此方法,您的Armor
类可以自行生成。但这种方法更干净吗?@Aeailmuawe是的,它使用多态性并确保不会忘记新的枚举常量。如果你可以重构你的类,使armorSlot不是设备的成员,你甚至可以通过在枚举中指定一个成员变量并在枚举的构造函数中设置它来简化这一点。请原谅我的无知,但我似乎不明白你的意思“通过在枚举中指定成员变量并在枚举的构造函数中设置它。“@Aeailmuawe枚举支持构造函数,您可以使用枚举常量将参数传递给构造函数。但仔细想想,这可能不适用于您的情况,因为ItemSlot是可变的,可能不属于ArmorType。我猜有可能有一个HashMap?