デフォルトでは、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
. modder が新しいTerrain
を追加するときは、それを実装Terrain
して に登録するだけですTerrainManager
。
static
イニシャライザは、他のオブジェクトが追加される前にオブジェクトが追加されるようにしますDefaultTerrain
。シングルトンを使用する場合、代わりにこれをクラス コンストラクターに入れることができます。
このパターンは、enum
ユーザーに追加してもらいたいさまざまなタイプに使用します。以外のほとんどすべてのタイプにも使用できますenum
。