在我的程序中,用户需要输入游戏的玩家类型。玩家是"human","good" (代表一个好的AI),"bad" (代表坏的AI)和"random" (对于一个随机的AI)。每个玩家都有自己的类,扩展了一个名为PlayerType的抽象类。
我的斗争是将一个String映射到这个对象,这样我就可以创建一个新的对象,使用字符串作为键,而B)从它的子类的对象中获取相关的String
最终,我只希望隐式String在代码中只出现一次,这样我可以在以后不进行重构的情况下修改它。
我试过只使用一个普通的HashMap,但是通过值搜索键似乎很麻烦。另外,我猜我必须使用getInstance()的Class方法,它不那么笨重,如果这是唯一的方法的话,这是可以的。
发布于 2015-09-16 17:05:39
我要做的是创建一个enum,它本质上作为给定类型的工厂。
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 + "]");
}
)因为这样你就可以这样称呼它:
String input = getInput();
PlayerTypes.create(input);当然,您将得到一个IllegalArgumentException,您可能需要通过再次获取输入来处理它。
编辑:显然在这种特殊情况下,您可以仅仅用
return PlayerTypes.valueOf(input).newPlayer();它也会做同样的事。我倾向于在enum中匹配附加的构造函数参数,所以我没有考虑使用valueOf(),但它肯定更干净。
EDIT2:获取该信息的唯一方法是在PlayerType类中定义一个抽象方法,该方法返回给定类型的PlayerTypes枚举。
public class PlayerType {
public abstract PlayerTypes getType();
}
public class GoodPlayer extends PlayerType {
@Override
public PlayerTypes getType() {
return PlayerTypes.GOOD;
}
}发布于 2015-09-16 17:19:26
我喜欢Epic提供的答案,但我不认为地图很笨重。因此,可以保留一个映射并直接获取构造函数调用。
Map<String, Supplier<PlayerType> map = new HashMap<>();
map.put("human", Human::new);
Human h = map.get("human").get(); 发布于 2015-09-16 17:19:07
我能想到的两个主要选择是:
使用Class.newInstance(),正如您所提到的(不确定您是否考虑到了这种方式):
// 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
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
}https://stackoverflow.com/questions/32614453
复制相似问题