默认情况下,enum
类型只有一组值。类型中的值enum
实际上声明为static final
,并且无法在运行时添加更多值。
话虽如此,您还可以使用其他模式来实现您想要的。让我们看一下使用接口和注册系统。我们将从Terrain
界面开始:
public interface Terrain {
int getId();
String getName();
int getSightBonus();
}
现在一个enum
, DefaultTerrain
:
public enum DefaultTerrain implements Terrain {
PLAINS(0, "Plains", 1),
HILLS(1, "Hills", -1),
MOUNTAINS(2, "Mountains", -2);
private int id;
private String name;
private int sightBonus;
private DefaultTerrain(int id, String name, int sightBonus) {
this.id = id;
this.name = name;
this.sightBonus = sightBonus;
}
public int getId() {return id;}
public String getName() {return name;}
public int getSightBonus() {return sightBonus;}
}
还有一个注册类,可以是静态实用程序类或单例。
public class TerrainManager {
private static Map<Integer, Terrain> terrainsById = new HashMap<>();
static {
for (DefaultTerrain terrain : DefaultTerrain.values())
register(terrain);
}
public static void register(Terrain terrain) {
Integer id = terrain.getId();
if (terrainsById.contains(terrain.getId()))
throw new IllegalArgumentException("Terrain with id already exists: " + id);
terrainsById.put(id, terrain);
}
public static Terrain getTerrainById(int id) {
return terrainsById.get(id);
}
public static Set<Terrain> getAllTerrains() {
return new HashSet<Terrain>(terrainsById.values());
}
}
最后一堂课是魔法发生的地方。大概模组制作者会在游戏的世界定义中使用某种标识符来表示“使用此图块”,对吧?在这种情况下,我称它为整数,id
但实际上它可以是任何类型,只需相应地修改Map
。在地图加载代码中,只需使用世界定义中的 ID 即可查找Terrain
. 当修改者添加一个新的Terrain
时,他们只需要实现Terrain
并注册它TerrainManager
。
static
初始化程序确保在添加任何其他内容之前添加您的对象DefaultTerrain
。如果您使用单例,则可以将其放入类构造函数中。
将此模式用于您enum
希望用户添加的不同类型。您也可以将它用于几乎任何其他类型,除了enum
.