首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用命令行创建新对象

使用命令行创建新对象
EN

Stack Overflow用户
提问于 2015-09-16 16:54:28
回答 4查看 1.6K关注 0票数 2

在我的程序中,用户需要输入游戏的玩家类型。玩家是"human""good" (代表一个好的AI),"bad" (代表坏的AI)和"random" (对于一个随机的AI)。每个玩家都有自己的类,扩展了一个名为PlayerType的抽象类。

我的斗争是将一个String映射到这个对象,这样我就可以创建一个新的对象,使用字符串作为键,而B)从它的子类的对象中获取相关的String

最终,我只希望隐式String在代码中只出现一次,这样我可以在以后不进行重构的情况下修改它。

我试过只使用一个普通的HashMap,但是通过值搜索键似乎很麻烦。另外,我猜我必须使用getInstance()Class方法,它不那么笨重,如果这是唯一的方法的话,这是可以的。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2015-09-16 17:05:39

我要做的是创建一个enum,它本质上作为给定类型的工厂。

代码语言:javascript
复制
public enum PlayerTypes {
    GOOD { 
        @Override
        protected PlayerType newPlayer() { 
            return new GoodPlayer();
        }
    }, 
    BAD {
        @Override
        protected PlayerType newPlayer() { 
            return new BadPlayer();
        }
    },
    RANDOM {
        @Override
        protected PlayerType newPlayer() { 
            return new RandomPlayer();
        }
    };

    protected abstract PlayerType newPlayer();

    public static PlayerType create(String input) {
        for(PlayerTypes player : PlayerTypes.values()) {
             if(player.name().equalsIgnoreCase(input)) {
                 return player.newPlayer();
             }
        }
        throw new IllegalArgumentException("Invalid player type [" + input + "]");
    }
)

因为这样你就可以这样称呼它:

代码语言:javascript
复制
String input = getInput();
PlayerTypes.create(input);

当然,您将得到一个IllegalArgumentException,您可能需要通过再次获取输入来处理它。

编辑:显然在这种特殊情况下,您可以仅仅用

代码语言:javascript
复制
return PlayerTypes.valueOf(input).newPlayer();

它也会做同样的事。我倾向于在enum中匹配附加的构造函数参数,所以我没有考虑使用valueOf(),但它肯定更干净。

EDIT2:获取该信息的唯一方法是在PlayerType类中定义一个抽象方法,该方法返回给定类型的PlayerTypes枚举。

代码语言:javascript
复制
public class PlayerType {
    public abstract PlayerTypes getType();
}

public class GoodPlayer extends PlayerType {
    @Override
    public PlayerTypes getType() {
        return PlayerTypes.GOOD;
    }
}
票数 4
EN

Stack Overflow用户

发布于 2015-09-16 17:19:26

我喜欢Epic提供的答案,但我不认为地图很笨重。因此,可以保留一个映射并直接获取构造函数调用。

代码语言:javascript
复制
Map<String, Supplier<PlayerType> map = new HashMap<>();
map.put("human", Human::new);
Human h = map.get("human").get(); 
票数 1
EN

Stack Overflow用户

发布于 2015-09-16 17:19:07

我能想到的两个主要选择是:

使用Class.newInstance(),正如您所提到的(不确定您是否考虑到了这种方式):

代码语言:javascript
复制
// Set up your map
Map<String, Class> classes = new HashMap<String, Class>();
classes.put("int", Integer.class);
classes.put("string", String.class);

// Get your data
Object s = classes.get("string").newInstance();

如果要使用带参数的构造函数( Class.getDeclaredConstructor ),可以使用示例

另一种选择是使用switch

代码语言:javascript
复制
Object getObject(String identifier) {
    switch (identifier) {
        case "string": return new String();
        case "int": return new Integer(4);
    }
    return null; // or throw an exception or return a default object
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32614453

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档