KotlinのEnumとは?複数の定数をまとめて扱う便利な記法「Enum」を解説
KotlinのEnum(列挙型)とは、複数の定数をまとめて扱うことができる便利な記法のことです。クラスの様に扱えますが、オブジェクトとなっていてインスタンス化できません。またEnumを使用すれば処理の抜け漏れの検知や共通化することもできます。
そんなEnumについて本記事では解説していくので一緒に学んでいきましょう。
目次
1.Enumとは
Enumとはenumerationの略で列挙、羅列、枚挙等の意味を持ち、定数(オブジェクト)のリストを保持する特別なクラス型です。KotlinではJavaと同様にEnumが使用できます。
2.Enumの基本
ここではEnumの宣言方法と利用例について解説していきます。
2-1.Enumの宣言
Enumを宣言する方法を見ていきましょう。
■Enumの宣言方法解説
まずKotlinでEnum宣言を記述するには、以下の様にEnum宣言と共にクラス名を書き、列挙型となるEnum定数を並べて書いていきます。
enum class Enumクラス名 { Enum定数, ・・・; }
■具体例
enum class PhoneBook { POLICE,RESCUE,TIMESIGNAL; }
定数は一般的に大文字を使いますので、それにならって記述しましょう。
2-2.Enumの利用例
Enumの定数を使用する時は“Enumクラス名.Enum定数“の形で利用できます。
またwhen文の入力にEnumを使用すれば、各条件にEnum定数全てが使用されているかIDEにてチェックが入り、処理の抜け漏れの検知がされます。
fun main() { val phoneBook = PhoneBook.RESCUE; parse(phoneBook)//消防です } enum class PhoneBook { POLICE, RESCUE, TIMESIGNAL; } fun parse(phoneBook: PhoneBook) { when (phoneBook) { PhoneBook.POLICE -> println("警察です") PhoneBook.RESCUE -> println("消防です") PhoneBook.TIMESIGNAL -> println("時報です")//例えばこの行が抜けていた場合IDEで警告が表示される。 } }
3.Enumの応用
ここではEnumにある様々な機能について見ていきましょう。
3-1. Enumの暗黙のメソッド・プロパティの仕様
Enumクラスには様々な暗黙のメソッド・プロパティが定義されています。
■プロパティ一覧
[Enum定数の暗黙のプロパティ]
| プロパティ | 説明 |
| Enum定数.name | Enum定数の文字列を返します |
| Enum定数.ordinal | Enum定数の位置を返します |
■使用例
fun main() { println("${PhoneBook.POLICE.name}:${PhoneBook.POLICE.ordinal}")//POLICE:0 println("${PhoneBook.RESCUE.name}:${PhoneBook.RESCUE.ordinal}")//RESCUE:1 println("${PhoneBook.TIMESIGNAL.name}:${PhoneBook.TIMESIGNAL.ordinal}")// TIMESIGNAL:3 } ・・・
■メソッド一覧
[列挙型の暗黙のメソッド]
| メソッド | 説明 |
| valueOf | 引数としてEnum定数名を取って、Enum型を返します |
| values | Array型として全Enum定数を返します |
後述のプログラムにて使用しますので動作を見てみましょう。
3-2. Enumにコンストラクタ、フィールド、メソッドを追加
Enumにコンストラクタ・フィールド・メソッドを追加する方法を見ていきましょう。
■コンストラクタとフィールドの設定例
クラス名の後ろに括弧を付けることでコンストラクタが設定できます。そして括弧の中にフィールドを持つこともできます。
fun main(args: Array) {//実行時引数入力値:POLICE val telClass = TelClass.valueOf(args[0]) println(telClass.phoneNo);//110 } enum class TelClass(val phoneNo: Int) { POLICE(110), RESCUE(119), TIMESIGNAL(117); }
■メソッド追加例1
クラス内で抽象メソッドを宣言すれば、Enum定数上で実装することができます。
fun main(args: Array) {//実行時引数:TIMESIGNAL val telClass = TelClass2.valueOf(args[0]) telClass.talk()//現在4時00分をお知らせします。 } enum class TelClass2 { POLICE { override fun talk() = "事件ですか?事故ですか?" }, RESCUE { override fun talk() = "消防ですか?救急ですか?" }, TIMESIGNAL { override fun talk() = "現在4時00分をお知らせします。" }; abstract fun talk(): String }
■メソッド追加例2
Enumクラスへ実装する物としてインターフェースを継承させることができます。ちなみにEnumクラスはオブジェクトとなるため他に継承させることはできません。また各Enum定数で共通化した処理を行う“ans()”メソッド、Enumクラスで使用できる“of()”メソッドを用意しています。
fun main() { println("電話番号を入力してください。") val telTo = readLine()?.let { TelProc.of(it.toInt()) } ?: throw RuntimeException() //"119"を入力 telTo.takeIf { !it.isChoose() } ?.let { println(it.talk()[0]) } ?: telTo.let { it.talk().forEachIndexed { index, str -> print("${index}:$str ") } //0:消防ですか? 1:救急ですか? println("\r\n0から${it.comeCarType().size - 1}の中のいずれかを選択してください。") //0から1の中のいずれかを選択してください。 readLine()?.toInt()?.let { num -> println(it.ans(num)) } //"0"を入力 //消防車を呼びます、少々お待ちください。 } } interface Tel { fun talk(): List fun isChoose(): Boolean fun comeCarType(): List fun ans(itemIndex: Int): String } enum class TelProc(val phoneNo: Int) : Tel { POLICE(110) { override fun talk() = listOf("事件ですか?", "事故ですか?") override fun isChoose() = true override fun comeCarType() = listOf("パトカー", "白バイ") }, RESCUE(119) { override fun talk() = listOf("消防ですか?", "救急ですか?") override fun isChoose() = true override fun comeCarType() = listOf("消防車", "救急車") }, TIMESIGNAL(117) { override fun talk() = listOf("現在4時00分をお知らせします。") override fun isChoose() = false override fun comeCarType() = emptyList() }; override fun ans(itemIndex: Int): String = comeCarType()[itemIndex] + "を呼びます、少々お待ちください。" companion object { fun of(phoneNo: Int) = values().first { it.phoneNo == phoneNo } } }
4.EnumをJavaと相互運用するときのtips
先ほどの例でcompanion objectが出てきましたが、JavaからKotlinのクラスを呼ぶ場合は“TelProc.Companion.of(hoge)”となってしまいます、そこで以下のようにメソッドに“@JmvStatic”をつけることで“TelProc.of(hoge)”と呼び出すことができます。
enum class TelProc(val phoneNo: Int) : Tel { ... companion object { @JvmStatic fun of(phoneNo: Int) = ... } }
5.さいごに
これで皆さんEnumマスターに成れましたね。Enumを使用する事で複数の値を効率良くまとめられます。ここで学んだことをぜひご活用ください。
コメント