Enumクラス
CoddyのKotlinジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 33/57。
enum class は値の集合が固定された型を宣言します。この値は定数です。各定数は、name と ordinal(0 から始まる位置)を持つ enum のオブジェクトです。entries はそれらを順番に一覧表示します。
enum class Direction { NORTH, EAST, SOUTH, WEST }main の中で:
val d = Direction.EAST
println(d)
println(d.ordinal)
println(Direction.entries)出力:
EAST
1
[NORTH, EAST, SOUTH, WEST]enum の定数にはプロパティを持たせて enum のコンストラクターに渡すことができ、enum はメソッドを宣言できます。セミコロンはメンバーの前で定数のリストを終了します。
enum class Coin(val cents: Int) {
PENNY(1), NICKEL(5), DIME(10), QUARTER(25);
fun label() = "${name.lowercase()} ($cents c)"
}main の内部:
println(Coin.DIME.label())
println(Coin.entries.sumOf { it.cents })出力:
dime (10 c)
41すべての定数を列挙する enum に対する when では else は必要なく、コンパイラーは不足している定数を報告します。valueOf("SOUTH") は完全一致する名前で定数を検索し、未知の名前に対しては例外をスローするため、入力には通常 entries.find を使って照合します。
enum class Direction { NORTH, EAST, SOUTH, WEST }
fun turnRight(d: Direction) = when (d) {
Direction.NORTH -> Direction.EAST
Direction.EAST -> Direction.SOUTH
Direction.SOUTH -> Direction.WEST
Direction.WEST -> Direction.NORTH
}
fun parse(text: String) = Direction.entries.find { it.name == text.uppercase() }main の中で:
println(turnRight(Direction.valueOf("SOUTH")))
println(parse("north"))
println(parse("up"))出力:
WEST
NORTH
null定数は独自の本体を持ち、そこでメソッドをオーバーライドできます。列挙型でメソッドを abstract として宣言すると、すべての定数にその実装が強制されます。
enum class Op(val symbol: String) {
PLUS("+") {
override fun apply(a: Int, b: Int) = a + b
},
TIMES("*") {
override fun apply(a: Int, b: Int) = a * b
};
abstract fun apply(a: Int, b: Int): Int
}main の中では次のようにします。
for (op in Op.entries) println("6 ${op.symbol} 3 = ${op.apply(6, 3)}")出力:
6 + 3 = 9
6 * 3 = 18チャレンジ
簡単列挙型 Size を、定数 SMALL(250 ml、価格 300)、MEDIUM(350 ml、380)、LARGE(500 ml、450)で完成させてください。価格の単位はセントです。label() は medium (350 ml): 3.80 を返し、upsize() は次に大きいサイズを返します。ただし、LARGE の場合は同じサイズを返します。コンパニオンの parse(text) は、大文字と小文字を区別せずに名前でサイズを検索するか、最初の文字(s、M)で検索し、それ以外の場合は null を返します。
提供されたコードは、medium、L、up small(サイズアップしたドリンク)などの注文を読み取り、各ラベルまたは unknown size x を出力し、最後に total: 11.10 を出力します。
コードは Size.kt に記述してください。Main.kt には提供された入出力コードが含まれており、編集できません。
自分で試してみよう
fun main() {
// 提供された入出力コード: そのままにしておく
val input = generateSequence(::readLine).toList()
var total = 0
for (line in input) {
val upsize = line.startsWith("up ")
val size = Size.parse(line.removePrefix("up "))
if (size == null) {
println("unknown size $line")
continue
}
val chosen = if (upsize) size.upsize() else size
println(chosen.label())
total += chosen.price
}
println("total: %d.%02d".format(total / 100, total % 100))
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
自分で練習してみよう: Kotlinプレイグラウンド