The HIRO Says

If you smell what The HIRO is cooking!!!

【enum】メソッドの定義(2)−インターフェースを使う方法

前回、1つの enum クラスの中で abstract メソッドと concrete メソッドを定義する方法を説明しました。
今回は、インターフェースを使って enum のメソッドを定義する方法を説明します。
ちなみに今回も、四則演算の例で説明します。


手順(1)−インターフェースを定義する

まず、計算を行う calculate メソッドを定義した、Operation インターフェースを定義します。
※インターフェースなので、メソッドに public とかつける必要はないです。

public interface Operation {
    double calculate(double x, double y);
}

手順(2)−enum でのインターフェースの実装

次に、上記(1)の Operation を実装する四則演算用の enum として、BasicOperation を定義します。
※混同を避けるため、前回の ArithmeticOperation と名前を分けました。
 やりたいことは同じです。


手順は次の通りです。

  1. インターフェースを実装(implements)する enum を定義します。
  2. 各定数で、メソッドを実装します。


こんな感じです。

// (1)インターフェースを実装した enum を定義する。
public enum BasicOperation implements Operation {

    // 加算
    PLUS("+") {
        // (2)各定数で、メソッドを実装する。
        public double calculate(double x, double y) {
            return x + y;
        }
    },

    // 減算
    MINUS("-") {
        public double calculate(double x, double y) {
            return x - y;
        }
    },

    // 乗算
    TIMES("*") {
        public double calculate(double x, double y) {
            return x * y;
        }
    },

    // 除算
    DIVIDE("/") {
        public double calculate(double x, double y) {
            return x / y;
        }
    };

    // 演算記号(※インスタンスメソッドなので注意!)
    private final String symbol;


    // コンストラクタ(演算記号を設定)
    private BasicOperation(String symbol) {
        this.symbol = symbol;
    }


    // (おまけ)toString で、演算記号を表示できるようにする!
    @Override
    public String toString() {
        return this.symbol;
    }

手順(3)−使い方

別に普通の enum として使えますが、それだけだと面白みに欠けるので、ちょっと味のある方法を2つ紹介します。

(a)Class#getEnumConstants() を使う方法

Class クラス(ややこしい)に、getEnumConstants() というメソッドがあります。
これは、Class クラス(ry が enum の場合、その enum の定数の配列を返してくれるメソッドです。
使い方は、次のようになります。

    double x = 8;
    double y = 2;

    for (Operation op : BasicOperation.class.getEnumConstants()) {
        System.out.printf(
                "%f %s %f = %f%n",
                x,
                op.toString(),
                y,
                op.calculate(x, y));
    }
(b)enum の values() を使う方法

enum には、その定数の配列を返してくれる values() メソッド(static)が自動的に用意されています。
これを使っても、同じことができます。

    double x = 8;
    double y = 2;

    for (Operation op : BasicOperation.values()) {
        System.out.printf(
                "%f %s %f = %f%n",
                x,
                op.toString(),
                y,
                op.calculate(x, y));
    }

メリット

インターフェースなので、定数だけ定義してメソッドを定義し忘れるといったことを防止できます。
(メソッドを定義し忘れると、コンパイルエラーで検知してくれます。)
あと、同じ理由で、違う実装の追加・切り替えも容易です。


NEXT

次回、enum でメソッドを定義する3つ目の方法として、Strategy パターンを使う方法を説明します。