Menu
Coddy logo textTech

Classes Enum

Fait partie de la section Programmation orientée objet du Journey Kotlin de Coddy. Leçon 33 sur 57.

Une enum class déclare un type avec un ensemble fixe de valeurs, ses constantes. Chaque constante est un objet de l’énumération avec un name et un ordinal, sa position commençant à 0. entries les répertorie dans l’ordre :

enum class Direction { NORTH, EAST, SOUTH, WEST }

À l’intérieur de main :

val d = Direction.EAST
println(d)
println(d.ordinal)
println(Direction.entries)

Résultat :

EAST
1
[NORTH, EAST, SOUTH, WEST]

Les constantes d’énumération peuvent avoir des propriétés, transmises au constructeur de l’énumération, et l’énumération peut déclarer des méthodes. Un point-virgule termine la liste des constantes avant les membres :

enum class Coin(val cents: Int) {
    PENNY(1), NICKEL(5), DIME(10), QUARTER(25);

    fun label() = "${name.lowercase()} ($cents c)"
}

Dans main :

println(Coin.DIME.label())
println(Coin.entries.sumOf { it.cents })

Sortie :

dime (10 c)
41

Un when portant sur une énumération qui répertorie toutes les constantes ne nécessite pas de else, et le compilateur signale toute constante manquante. valueOf("SOUTH") trouve une constante par son nom exact et lève une exception si elle est inconnue ; l’entrée est donc généralement recherchée avec 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() }

Dans main :

println(turnRight(Direction.valueOf("SOUTH")))
println(parse("north"))
println(parse("up"))

Sortie :

WEST
NORTH
null

Une constante peut avoir son propre corps et y redéfinir une méthode. Déclarer la méthode abstract dans l’énumération force chaque constante à l’implémenter :

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
}

Dans main :

for (op in Op.entries) println("6 ${op.symbol} 3 = ${op.apply(6, 3)}")

Sortie :

6 + 3 = 9
6 * 3 = 18
challenge icon

Défi

Facile

Complétez l’énumération Size avec les constantes SMALL (250 ml, prix 300), MEDIUM (350 ml, 380) et LARGE (500 ml, 450), les prix étant exprimés en centimes. label() renvoie medium (350 ml): 3.80, et upsize() renvoie la taille immédiatement supérieure, ou la même taille pour LARGE. La méthode parse(text) de l’objet compagnon recherche une taille par son nom sans tenir compte de la casse, ou par sa première lettre (s, M), et renvoie null dans le cas contraire.

Le code fourni lit des commandes telles que medium, L ou up small (la boisson dans une taille supérieure) et affiche chaque libellé ou unknown size x, puis finalement total: 11.10.

Votre code doit être placé dans Size.kt. Main.kt contient le code fourni pour les entrées et sorties et ne peut pas être modifié.

Essayez vous-même

fun main() {
    // Code d'entrée/sortie fourni : gardez-le tel quel
    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))
}
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Programmation orientée objet

Entraînez-vous par vous-même : Playground Kotlin