115

反対方向を返すメソッドを持つ 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);
     }
}
4

6 に答える 6

216

タイトルに惹かれた人のために: はい、列挙型で独自のメソッドを定義できます。このような非静的メソッドを呼び出す方法を知りたい場合は、他の非静的メソッドと同じ方法で実行します。つまり、そのメソッドを定義または継承する型のインスタンスで呼び出します。列挙型の場合、そのようなインスタンスは単にENUM_CONSTANTs です。

必要なのは だけです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 コメントを説明するためのもう少し「ハックな」方法ですが、フィールドを追加したり順序を変更したりするとコードが壊れるため、最初のアプローチほど柔軟ではありません。

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]; 
    }
}
于 2013-09-18T23:01:25.517 に答える
164

このような小さな列挙型の場合、最も読みやすい解決策は次のとおりです。

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();

}
于 2013-09-18T23:06:24.080 に答える
29

これは機能します:

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");
    }
}
于 2014-11-19T17:50:10.343 に答える
15

抽象メソッドを作成し、各列挙値でそれをオーバーライドします。作成中に反対のことを知っているので、動的に生成または作成する必要はありません。

ただし、うまく読めません。おそらく、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();
}
于 2013-09-18T23:04:11.877 に答える
4

はい、常に行っています。新しいオブジェクトではなく、静的インスタンスを返します

 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;
 }
于 2013-09-18T23:00:05.507 に答える