この場合、できることはあまりありません。より複雑な例であっても、共通コードを配置するのに最適な場所は、すべての列挙型が使用できるユーティリティ クラスか、列挙型に含まれる別のクラスです。コンポジション経由 (各列挙型には、おそらく Keyword と呼ばれるそのクラスのインスタンスがあります)。
メソッドのコードtoString
が複雑で、各列挙でそれを再記述したり、含まれているオブジェクトに移動したりしたくない場合、Java 8 には使用できるメカニズムがあります。この例ではやり過ぎです。列挙型がすべて使用するインターフェイスを定義できます。インターフェイスは状態を持つことができないため、状態 (キーワード) は引き続き列挙型に存在する必要がありますが、Java 8 以降では、メソッドのデフォルトの実装を提供できます。
public interface Common {
String getKeyword();
String toString() default {
return getKeyword();
}
String toDescriptiveString() default {
char firstLetter = getKeyword().charAt(0);
boolean vowel =
firstLetter == 'a' || firstLetter == 'e' ||
firstLetter == 'i' || firstLetter == 'o' ||
firstLetter == 'u' || firstLetter == 'x';
// the letter x is pronounced with an initial vowel sound (eks)
return (vowel?"an ":"a ") + getKeyword() + " address";
}
}
あなたの列挙型はこのインターフェースを実装します:
public enum AddressSubType implements Common {
DOM("dom"), INTL("intl"), POSTAL("postal");
private final String keyword;
private AddressSubType(String keyword) {
this.keyword = keyword;
}
@Override
public String getKeyword() {
return keyword;
}
@Override
public String toString() {
return Common.super.toString();
}
}
public enum EmailSubType implements Common {
INTERNET("internet"), X400("x.400");
private final String keyword;
private EmailSubType(String keyword) {
this.keyword = keyword;
}
@Override
public String getKeyword() {
return keyword;
}
@Override
public String toString() {
return Common.super.toString();
}
}
toString
メソッドの奇妙な新しい構文に注目してください。インターフェースのデフォルト メソッドの規則は、メソッド解決が常にインターフェースよりもクラス メソッドを優先することです。したがって、toString
inのデフォルトの実装を提供しても、enum の実装Common
が優先され、enum に実装Object
がない場合は in の実装が優先されます。Object
したがって、 ( toString
、 またはhashCode
、 または など)のメソッドの 1 つに取って代わるインターフェイスの既定のメソッドを使用する場合は、equals
この新しいinterface.super.method()
構文で明示的に呼び出す必要があります。
toDescriptiveString
ただし、メソッドのために余分なフープをジャンプする必要はありません。これは の新しいものでinterface Common
あり、enum によって提供されないため、インターフェースによって提供されるデフォルトの実装を取得します。(独自のメソッドでオーバーライドしたい場合は、他の継承されたメソッドと同じようにできます。)
もちろん、オブジェクトの他のメソッドと同様に、デフォルトのメソッドを使用できます。
public class Test {
public static void main(String[] args) {
for (AddressSubType a : AddressSubType.values()) {
System.out.println(a.toDescriptiveString());
}
for (EmailSubType e : EmailSubType.values()) {
System.out.println(e.toDescriptiveString());
}
}
}
どちらが出力されますか:
dom アドレス
国際アドレス
住所
インターネットアドレス
x.400 アドレス
ただし、この場合、かなり冗長なtoDescriptiveString
メソッドがなければ、enum クラスは、ない場合よりも少し短くなることはありませんinterface Common
。インターフェースのデフォルト メソッドは、既存のインターフェースに新しい機能を追加する場合に真価を発揮します。これは、以前のバージョンの Java のインターフェースのすべての実装者を壊さない限り不可能なことです。
これらはすべて、 Lambda を使用したまだ不完全な Java SE 8 に基づいています。プレリリース ビルドをダウンロードできますが、これは進行中の作業であることに注意してください。