私は反対の方向を返すメソッドを持つenum Directionを宣言したいと思います(以下は構文的に正しくありません、つまりenumをインスタンス化することはできませんが、それは私のポイントを示しています)。これはJavaで可能ですか?
コードは次のとおりです。
public enum Direction {
NORTH(1),
SOUTH(-1),
EAST(-2),
WEST(2);
Direction(int code){
this.code=code;
}
protected int code;
public int getCode() {
return this.code;
}
static Direction getOppositeDirection(Direction d){
return new Direction(d.getCode() * -1);
}
}
ここでタイトルに魅了された人のために:はい、enumで独自のメソッドを定義できます。このような非静的メソッドを呼び出す方法を知りたい場合は、他の非静的メソッドと同じ方法で行います。そのメソッドを定義または継承するタイプのインスタンスで呼び出します。列挙型の場合、そのようなインスタンスは単純にENUM_CONSTANT
sです。
したがって、必要なのはEnumType.ENUM_CONSTANT.methodName(arguments)
だけです。
次に、質問から問題に戻りましょう。解決策の1つは
public enum Direction {
NORTH, SOUTH, EAST, WEST;
private Direction opposite;
static {
NORTH.opposite = SOUTH;
SOUTH.opposite = NORTH;
EAST.opposite = WEST;
WEST.opposite = EAST;
}
public Direction getOppositeDirection() {
return opposite;
}
}
これで、Direction.NORTH.getOppositeDirection()
はDirection.SOUTH
を返します。
@ jedwards comment を説明するためのもう少し「ハックな」方法ですが、フィールドを追加したり順序を変更するとコードが壊れるので、最初のアプローチほど柔軟ではありません。
public enum Direction {
NORTH, EAST, SOUTH, WEST;
// cached values to avoid recreating such array each time method is called
private static final Direction[] VALUES = values();
public Direction getOppositeDirection() {
return VALUES[(ordinal() + 2) % 4];
}
}
このような小さな列挙型の場合、最も読みやすいソリューションは次のとおりです。
public enum Direction {
NORTH {
@Override
public Direction getOppositeDirection() {
return SOUTH;
}
},
SOUTH {
@Override
public Direction getOppositeDirection() {
return NORTH;
}
},
EAST {
@Override
public Direction getOppositeDirection() {
return WEST;
}
},
WEST {
@Override
public Direction getOppositeDirection() {
return EAST;
}
};
public abstract Direction getOppositeDirection();
}
これは動作します:
public enum Direction {
NORTH, SOUTH, EAST, WEST;
public Direction oppose() {
switch(this) {
case NORTH: return SOUTH;
case SOUTH: return NORTH;
case EAST: return WEST;
case WEST: return EAST;
}
throw new RuntimeException("Case not implemented");
}
}
抽象メソッドを作成し、列挙値ごとにオーバーライドします。作成中は逆のことがわかっているため、動的に生成または作成する必要はありません。
しかし、うまく読みません。おそらくswitch
の方が管理しやすいでしょうか?
public enum Direction {
NORTH(1) {
@Override
public Direction getOppositeDirection() {
return Direction.SOUTH;
}
},
SOUTH(-1) {
@Override
public Direction getOppositeDirection() {
return Direction.NORTH;
}
},
EAST(-2) {
@Override
public Direction getOppositeDirection() {
return Direction.WEST;
}
},
WEST(2) {
@Override
public Direction getOppositeDirection() {
return Direction.EAST;
}
};
Direction(int code){
this.code=code;
}
protected int code;
public int getCode() {
return this.code;
}
public abstract Direction getOppositeDirection();
}
はい、私たちは常にそれを行います。新しいオブジェクトではなく、静的インスタンスを返します
static Direction getOppositeDirection(Direction d){
Direction result = null;
if (d != null){
int newCode = -d.getCode();
for (Direction direction : Direction.values()){
if (d.getCode() == newCode){
result = direction;
}
}
}
return result;
}
public enum Direction {
NORTH, EAST, SOUTH, WEST;
public Direction getOppositeDirection(){
return Direction.values()[(this.ordinal() + 2) % 4];
}
}
列挙には、宣言された順序で列挙のすべての値を含む配列を返す静的な値メソッドがあります。 ソース
nORTHは1を取得するため、EASTは2を取得し、SOUTHは3を取得し、WESTは4を取得します。単純な方程式を作成して、反対の方程式を取得できます。
(値+ 2)%4