我有以下枚举类字符和枚举类项:
public enum Item
{
COOKIE("cookie"), CRISPS("crisps"), DRINK("drink");
private String description;
/**
* Constructor with description and weight.
* Pre-condition: description not null.
*/
private Item(String description)
{
assert description != null : "Item.Item with null description";
this.description = description;
sane();
}
字符:
public enum Character
{
JESS("Jess", 0.5f,Item.SANDWICH), SALLY("Sally",0.5f, Item.CRISPS),
ANDREW("Andrew" ,0.5f,Item.DRINK),
ALEX("Alex",0.5f,null),CookieMonster("CookieMonster",1.0f,null),
CookieGiver("CookieGiver",1.0f,null),Player("Player",0.0f,null);
private String description;
private ArrayList<Item> charItems = new ArrayList<Item>();
private float probability;
/**
* Constructor initialising description,item and probability.
*/
private Character(String desc,float moveProbability,Item items)
{
description= desc;
charItems.add(items);
probability =moveProbability;
}
public void enterRoom(Room r)
{
}
以下是用于创建 Room 对象的类
public class Room
{
private String description;
private HashMap<Direction, Room> exits; // stores exits of this room.
private Set<Character> chars; // stores the characters that are in this
room.
/**
* Create a room described "description". Initially, it has
* no exits. "description" is something like "a kitchen" or
* "an open court yard".
* @param description The room's description.
* Pre-condition: description is not null.
*/
public Room(String description)
{
assert description != null : "Room.Room has null description";
this.description = description;
exits = new HashMap<Direction, Room>();
chars = new HashSet<Character>();
sane();
}
我将如何在枚举类中编写一个方法,例如当调用时,CookieGiver 将物品 COOKIE 提供给房间中的每个角色?
我知道不知何故我需要使用 HashSet 字符,但我想不出一种方法来做到这一点。
向Room
添加一个 getter 以获取房间中的角色列表
public Set<Character> getChars() {
return chars;
}
将方法添加到字符枚举以将项目添加到已持有的项目列表中。
private void addItem(Item item) {
charItems.add(item);
}
在enterRoom
方法中,对于房间中的每个字符,调用addItem
,向其添加 COOKIE。
注意:如果多次调用,它将添加多个 COOKIE。如果您不希望这样做,则必须检查 COOKIE 是否已经存在或使用 Set。
public void enterRoom(Room r) {
for(Character character : r.getChars()) {
character.addItem(Item.COOKIE);
}
编辑:
由于您希望上述策略仅适用于CookieGiver
,一种方法是将enterRoom
的默认逻辑设为空,并将其覆盖为 CookieGiver
。
public void enterRoom(Room r) { } //empty / no-op in enum
CookieGiver("CookieGiver", 1.0f, null) {
@Override
public void enterRoom(Room r) {
for (Character character : r.getChars()) {
character.addItem(Item.COOKIE);
}
}
选项 2:
您可以创建一个私有嵌套枚举,其中包含调用enterRoom
时要执行的操作的策略。然后每个角色都会有一个针对它的策略。
public enum Character {
JESS("Jess", 0.5f, Item.CRISPS, RoomStrategy.NONE), //when enterRoom is called on this Character, then there is nothing to do
CookieMonster("CookieMonster", 1.0f, null, RoomStrategy.NONE),
CookieGiver("CookieGiver", 1.0f, null, RoomStrategy.PROVIDE_COOKIE), //when enterRoom is called on this Character, then invoke the logic corresponding to PROVIDE_COOKIE
private String description;
private ArrayList<Item> charItems = new ArrayList<Item>();
private float probability;
private RoomStrategy roomStrategy; //Field to hold the strategy
/**
* Constructor initialising description,item and probability.
*/
private Character(String desc, float moveProbability, Item items, RoomStrategy roomStrategy) {
description = desc;
charItems.add(items);
probability = moveProbability;
this.roomStrategy = roomStrategy;
}
private void addItem(Item item) {
charItems.add(item);
}
public void enterRoom(Room r) {
roomStrategy.enterRoom(r); //Just delegate to the strategy
}
private enum RoomStrategy { //better name needed?
NONE {
@Override
void enterRoom(Room r) {
//No op
}
},
PROVIDE_COOKIE {
@Override
void enterRoom(Room r) {
for (Character character : r.getChars()) {
character.addItem(Item.COOKIE);
}
}
};
abstract void enterRoom(Room r);
}
}
注意:按照评论中的建议,有更好的方法可以做到这一点。