Menu
Coddy logo textTech

Classes Enum

Parte da seção Programação Orientada a Objetos do Journey de Kotlin da Coddy. Lição 33 de 57.

Uma enum class declara um tipo com um conjunto fixo de valores, suas constantes. Cada constante é um objeto do enum com um name e um ordinal, sua posição começando em 0. entries as lista em ordem:

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

Dentro de main:

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

Saída:

EAST
1
[NORTH, EAST, SOUTH, WEST]

As constantes de enum podem ter propriedades, passadas ao construtor do enum, e o enum pode declarar métodos. Um ponto e vírgula encerra a lista de constantes antes dos membros:

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

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

Dentro de main:

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

Saída:

dime (10 c)
41

Um when sobre uma enumeração que lista todas as constantes não precisa de else, e o compilador informa qual constante está ausente. valueOf("SOUTH") encontra uma constante pelo nome exato e lança uma exceção para uma desconhecida, portanto a entrada geralmente é correspondida com 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() }

Dentro de main:

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

Saída:

WEST
NORTH
null

Uma constante pode ter seu próprio corpo e substituir um método nele. Declarar o método abstract no enum força cada constante a implementá-lo:

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
}

Dentro de main:

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

Saída:

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

Desafio

Fácil

Complete o enum Size com as constantes SMALL (250 ml, preço 300), MEDIUM (350 ml, 380) e LARGE (500 ml, 450), com os preços em centavos. label() retorna medium (350 ml): 3.80, e upsize() retorna o próximo tamanho maior, ou o mesmo tamanho para LARGE. O companion, por meio de parse(text), encontra um tamanho pelo nome, ignorando maiúsculas e minúsculas, ou pela primeira letra (s, M), e retorna null caso contrário.

O código fornecido lê pedidos como medium, L ou up small (a bebida aumentada) e imprime cada rótulo ou unknown size x, e, por fim, total: 11.10.

Seu código deve ficar em Size.kt. Main.kt contém o código fornecido de entrada/saída e não pode ser editado.

Experimente você mesmo

fun main() {
    // Código de entrada/saída fornecido: mantenha-o como está
    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 iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Programação Orientada a Objetos

Pratique por conta própria: Playground de Kotlin