⑦列挙型Enumについて
列挙型Enum
カードのスートのように、特定の種類以外は存在しえないような概念
そういったものを定義するのが列挙型Enumです(以下Enum)
実例を挙げるとすると、注文の状態などでしょうか
「支払待」「在庫不足」「発送可能」「発送済」「配送完了」
我々も注文をした後に発送状況など確認すると思いますが
おそらくそこの表記も、Enumと似た概念で実装されているはずです
発送状況:「盆踊り中」とか適当な状態書かれてたらウケますね
記述例と構文説明
Enumの定義
public enum SeasonEnum {
SPRING, SUMMER, AUTUMN, WINTER;
}
上記は四季をEnumとして記述した例です
四季も、日本では春夏秋冬の4つしかありませんよね
Enumを定義するときは、クラスを定義するときと同様javaファイルを作ります
そのうえで、クラスであれば「public class クラス名」となるところを
「public enum Enum名」としてあげます
中身は、Enumで定義したい要素をカンマ区切りで列挙します
全部大文字なのは慣習です
慣習ついでに…
上の記述例では要素を横一列に並べていますが
(カンマ区切り・行末の;の必要性を強調しています)
過去に僕がいた案件では、下記のように縦に並べる様に列挙してました
public enum SeasonEnum {
SPRING,
SUMMER,
AUTUMN,
WINTER;
}
Enumの宣言
SeasonEnum season = SeasonEnum.SPRING;
Enum型の変数を宣言するときは、上記のようにEnum名と要素をつなぎます
メソッド呼び出しの時に使っている、ドット演算子の考え方と同じです
要は「SeasonEnumという列挙型のなかのSPRINGという要素」と言う意味です
つぎに、宣言したEnumを出力してみるとどうなるのでしょうか
System.out.pringln(season)

このように、定義したEnumの要素がそのまま表示されます
当たり前っちゃ当たり前…な気がしますね
それでは…
「画面に出力する文字列は日本語がいい」
と言われたらどのように実装しましょうか
Enumの要素名を日本語にする…は、ちょっとナシにしましょう (できるけど)
Enumの要素名はそのままに、表示名を変える
それを実現させるために、次の記述を加えます
Enumの各要素に属性を持たせる
public enum SeasonEnum {
SPRING("春"),
SUMMER("夏"),
AUTUMN("秋"),
WINTER("冬");
String jpnName;
private SeasonEnum(String jpnName) {
this.jpnName = jpnName;
}
public String getJpnName() {
return this.jpnName;
}
}
急にドカッと記述が増えました
頭が痛くなってきたかもしれませんが、少しだけ辛抱を
もしかしたら、ところどころ知っている概念があるかもしれません
まず、Enumの各要素の後ろに()がついて、中に日本語名が入っています
そして、Enumの要素とは別にjpnNameなる変数が増えていて…
なんかメソッドも新しく2つ作られています
わかりやすいところからいきましょう
jpnNameという変数が急に生まれたことを仮に受け入れるとして
した二つのメソッドは、コンストラクタと、アクセサ(ゲッター)
に見えませんか?
見えませんか?というか、ズバリそのものなんですが
public enum SeasonEnum {
SPRING("春"),
SUMMER("夏"),
AUTUMN("秋"),
WINTER("冬");
String jpnName;
// コンストラクタ
// ただし、可視性はprivate
private SeasonEnum(String jpnName) {
this.jpnName = jpnName;
}
// ゲッター
public String getJpnName() {
return this.jpnName;
}
}
変数が生まれた意味は置いておいて…
「属性を持たせたくなったら、コンストラクタとゲッターは実装する!」
そういう決め事と一旦とらえておきましょう。
そして、決め事ついでに、「Enumのコンストラクタの可視性はprivate」です
さて、残った謎は「jpnName」なる変数が生まれた理由です
そもそも、今の変更を加えることになった理由は
「英名ではなく和名表示をしたい」からでした
つまり…
SPRINGに、自身の名前(英)のほかに”春”という名前(和)を持たせたい
SUMMERに、自身の名前(英)のほかに”夏”という名前(和)を持たせたい
AUTUMNに、自身の名前(英)のほかに”秋”という名前(和)を持たせたい
WINTERに、自身の名前(英)のほかに”冬”という名前(和)を持たせたい
ということです
ところで、これらの”春”,”夏”,”秋”,”冬”は、データ型で表すとしたらなんでしょう
そして、jpnNameは何型で定義されているでしょうか
なんとなーく、わかってきた気がしませんか
ここで、情報を増やしてみましょう
「春夏秋冬に1-4の順番を持たせたい」
こうした場合、どういう記述に変わるでしょうか
public enum SeasonEnum {
SPRING("春", 1), ......①
SUMMER("夏", 2),
AUTUMN("秋", 3),
WINTER("冬", 4);
String jpnName; ......②
int number;
// コンストラクタ ......③
private SeasonEnum(String jpnName, int number) {
this.jpnName = jpnName;
this.number = number;
}
/* アクセサは記載省略 */ ......④
}
このようになります
つまり、Enumの各要素に情報を付け足したくなった場合は
①Enumの各要素の後ろに()をつけて、与えたい情報を記載する
②与えた情報と同じ型の変数を属性として定義する
③定義した変数を持つ引数有コンストラクタを定義する
ただし可視性はprivate
④必要に応じて変数のアクセサを用意する
長かったですね……
Enumは慣れてしまえば使いやすいものの、ハードルの高い概念だと思います
一度ですべて覚えきろうとせず、逐一戻りながら実装してみましょう
何度も言いますが、勉強会中であれば聞いてもらって構いません
課題5 Enumでスートを定義する
①Enumでスートを定義してみましょう
Enum名:SuitEnum
各スートの英字表記
SPADE
HEART
DIA
CLUB
②Enumの各要素に、和名の属性を追加しましょう
スペード
ハート
ダイヤ
クラブ
③いずれかのEnumを変数として宣言し、和名で出力させてみましょう