enumには抽象メソッドが書ける

世間的にはきっと常識なんでしょうけど知らなかったのでメモ。


enumに振る舞いを実装して、ある種のStrategy的に扱いたい場面ってのは結構あると思います。
今まで僕は以下の様な書き方か、あるいはenumの値によって適切なStrategyクラスを返すファクトリを作ったりしていました。

public enum HogeType {
  TYPE1,
  TYPE2,
  ;

  public int calc(int a, int b){
    int result;
    switch(this){
      case TYPE1:
        //何かしらの処理
      case TYPE2:
        //何かしらの処理
      default:
        //何かしらの処理
    }
    return result;
  }
}


問題点として

  1. タイプ値を追加した時に振る舞いを追加するのを忘れるかも(タイプ値に依存するメソッドが複数あればなおのこと)
  2. タイプ値が多くなればなるほどメソッドが長くなる
  3. 見通しが悪い
  4. 結局Strategyクラス作るなら意味無いじゃん

などなど。


ところが最近(今更過ぎますが)enumに抽象メソッドを書けることを知りました。
それを利用すると上のコードは以下のように書き換えられます。

public enum HogeType{
  TYPE1{
    @Override
    public int calc(int a, int b){
      int result;
      //何かしらの処理
      return result;
    }
  },

  TYPE2{
    @Override
    public int calc(int a, int b){
      int result;
      //何かしらの処理
      return result;
    }
  },
  ;

  public abstract int calc(int a, int b);
}


これだと

  1. コンパイラが叱ってくれるので振る舞いの追加を忘れることはない
  2. 一つのメソッドにタイプ値ごとの全振る舞いを書かなくていいのでメソッドがビッグにならない
  3. タイプ値に関する振る舞いがタイプ値ごとにまとまるのでわかりやすい
  4. クラス作る必要もなし

という感じで世界が平和になり、戦争や差別がなくなるのも時間の問題といった感じです。


べんりべんり。