【问题标题】:How to create an object by pulling the type from a variable?如何通过从变量中提取类型来创建对象?
【发布时间】:2013-07-16 00:50:19
【问题描述】:

我一直在使用 Java 开发一个关卡阅读器,它可以从我的游戏的 XML 文档中提取关卡数据。一切都很顺利,但是我遇到了一个问题。我从文档中提取的一件事是要创建的游戏对象的 ID。我有一堆类,如墙、播放器和硬币,它们都扩展了一个 GameObject 类。我想在 GameObject 类中有一个基于 ID 返回 GameObject 的方法。像这样的:

public GameObject CreateGameObject(int id, int x, int y, GameScreen parent) {
    Type type = getTypeFromList(id);
    Type gobj = new Type(x,y,parent);
    return gobj;
}

我知道我可以使用一堆 if 语句来检查 ID 并返回正确的 ID,但我希望代码更简洁、更通用。如果你能帮助告诉我如何做到这一点,或者告诉我另一种方式,我将不胜感激。

【问题讨论】:

  • 你的任务不清楚,代码非常混乱。尝试提供更好的解释。
  • 你最好把这个职责委托给另一个类,一个负责创建游戏对象的工厂类,你的游戏的任何其他部分都可以在需要时向这个类查询新对象。你甚至可以让它变得更智能,并使用 HashMap 之类的东西实现缓存,并让它返回不需要再次创建的所需对象。

标签: java class types


【解决方案1】:

我建议使用工厂接口创建GameObject,并为每种类型提供一个实现(如arynaq mentioned in the comments):

interface GameObjectFactory {
    GameObject create(); // this could also take arguments like x, y, and parent
}

private static final Map<Integer, GameObjectFactory> FACTORIES_BY_ID;
static {
    final Map<Integer, GameObjectFactory> factoriesById = new HashMap<>();

    // ID 42 is for walls
    factoriesById.put(42, new GameObjectFactory() {
        @Override
        public GameObject create() {
            return new Wall();
        }
    });

    //etc.

    FACTORIES_BY_ID = factoriesById;
}

如果 ID 是连续的,您也可以使用数组:

private static final GameObjectFactory[] FACTORIES = {
    // ID 0 is for walls
    new GameObjectFactory() {
        @Override
        public GameObject create() {
            return new Wall();
        }
    }
};

enum 也可以工作:

enum GameObjectFactory {

    WALL(42) {
        @Override
        GameObject create() {
            return new Wall();
        }
    };

    private final int id;

    private GameObjectFactory(int id) {
        this.id = id;
    }

    abstract GameObject create();

    static GameObjectFactory getById(int id) {
        for (GameObjectFactory factory : values()) {
            if (factory.id == id) {
                return factory;
            }
        }
        throw IllegalArgumentException("Invalid ID: " + id);
    }
}

【讨论】:

  • 谢谢!我认为不应该使用枚举方式。
猜你喜欢
  • 1970-01-01
  • 2010-10-31
  • 2020-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-02
  • 2012-08-30
  • 2011-08-19
相关资源
最近更新 更多