読者です 読者をやめる 読者になる 読者になる

No Programming, No Life

新しいNPNLです。http://d.hatena.ne.jp/fumokmm/ から引っ越してきました。

Javaのenumは継承できないけどインタフェースが継承できる

Java enum Tips

はじめに

Javaenumって便利ですよね。enumを使い続けていくとグルーピングしたくなってくる事があると思いますが、継承はできないので、そんな場合はインタフェースを実装してやるといいようです。

とりあえずテストを書いた

解説

インタフェース
interface Colored {
  String getColor();
}

まず、こんな感じのenumに付けるインタフェースを用意します。Coloredは色付けされたものという意味なので、#getColor()できるはずですね。

enum定義
enum Food implements Colored {
  rice { @Override public String getColor() { return "白"; } }, // こめ
  bread { @Override public String getColor() { return "白と茶"; } }, // ぱん
  noodle { @Override public String getColor() { return "白"; } }, // めん
  ;
}

enumの定義時にインタフェースを実装してあげます。これは直接実装していってますが、プライベートコンストラクタで値を受け取る方法でも可能です。

enum Animal implements Colored {
  cat("白と黒と茶"), // ねこ
  tiger("黄と黒"), // とら
  lion("茶"), // らいおん
  goat("白"), // やぎ
  sheep("白"), // ひつじ
  ;
  private String color;
  private Animal(String color) { this.color = color; }
  @Override public String getColor() { return this.color; }
}
使ってみる
Colored colored1 = Animal.cat;
Colored colored2 = Food.rice;

これで、定義したenumはColoredとしても扱えるようになりました。あとはお好きな場面でColored型として利用するだけです。

補足

今回作ったインタフェースのColoredは#getColor()メソッドしか定義していませんので、enumにもとからあるメソッド(#name()とか)は当然の事ながら使えません。なので、必要に応じてinterfaceの方に加えておくとよいでしょう。

interface Colored {
  String getColor();
  String name(); // ← 追加!
}

こうしておけば、enumはもとから#name()は持っているので、そのままenum側のコードには何も手を加えずに、Coloredとしても#name()を利用できるようになります。