Java:在列表中添加或删除元素时避免使用'instanceof'

时间:2013-01-19 21:56:49

标签: java arraylist instanceof

我正在制作一款游戏。游戏有GameMap。为了跟踪GameMap上的事物状态,我想为每个事物创建ArrayLists。问题是,我不想创建单独的方法来添加或从每种类型的ArrayList中删除项目。我是新手,所以当然我能想到的第一件事是'instanceof'运算符。

请记住,目前,GameMap是一个离散类,而不是接口或抽象类。目的是在初始化游戏时实例化GameMap对象。

public class GameMap {

//GameMap has a name
private String mapName;

//GameMap has rooms
private ArrayList<Room> roomsOnMap;

//GameMap has items
private ArrayList<Item> itemsOnMap;

//GameMap has people
private ArrayList<Person> peopleOnMap;

//construct GameMap with rooms, items, and people
private GameMap(String mapName, ArrayList someRooms, ArrayList someItems, ArrayList somePeople)
{
    this.mapName = mapName;
    this.roomsOnMap = someRooms;
    this.itemsOnMap = someItems;
    this.peopleOnMap = somePeople;
}

public void addObject(Object o)
{
    //HOW DO I AVOID THIS?
    if(o instanceof Room)
    {
        roomsOnMap.add((Room) o);
    }
    else if(o instanceof Item)
    {
        itemsOnMap.add((Item) o);
    }
    else if(o instanceof Person)
    {
        peopleOnMap.add((Person) o);
    }
}

4 个答案:

答案 0 :(得分:6)

使用overloaded方法:

void addObject(Room room) {
  roomsOnMap.add(room);
}

void addObject(Item item) {
  itemsOnMap.add(item);
}

..

答案 1 :(得分:2)

这是一招:

Map<Class, ArrayList> map = new HashMap<Class, ArrayList>();
map.put(Room.class, roomsOnMap);
map.put(Item.class, itemsOnMap);
map.put(Person.class, peopleOnMap);

// ...

public void addObject(Object o)
{
    map.get(o.getClass()).add(o); // be aware of NullPointerException here
}

尽管如此,我建议使用重载方法。

答案 2 :(得分:2)

你预感instanceOf可能不是一个好主意。

如果客房,物品和人员是某种“GameElements”或“MapElements”,您可以通过共同的父母与他们建立关系:

enum ElementType
{
    PERSON, ITEM, ROOM;
}

interface MapElement
{
    public ElementType getType();
}

class Room implements MapElement
{
    public ElementType getType()
    {
        return ElementType.ROOM;
    }
    //other attributes and methods...
}

class Person implements MapElement
{
    public ElementType getType()
    {
        return ElementType.PERSON;
    }
    //other attributes and methods...
}

class Item implements MapElement
{
    public ElementType getType()
    {
        return ElementType.ITEM;
    }
    //other attributes and methods...
}

然后您的add方法可以在此界面上运行

public void addObject(MapElement e)
{
    if(e.getType == ElementType.Room)
    {
        roomsOnMap.add((Room) e);
    }
    ...
}

仅在元素相关时才执行此操作。如果不是,您应该有单独的方法。使用单一方法执行此操作可能看起来很有效,但您无法获得任何收益。对于使用此类(以及编写它的开发人员)的任何类,单独的添加方法(如果元素不相关)比使用Object作为参数的通用添加更直观。如果事实上你的类和方法变得更加直接,那么你不会失去任何方式,甚至不会丢失几行代码。

答案 3 :(得分:1)

如果您想避免使用instanceof,请尝试Visitor设计模式。

您可以在这里找到它的描述:http://www.oodesign.com/visitor-pattern.html