Icono del sitio Develou

Clases enum En Kotlin

En este tutorial aprenderás a declarar clases enum en Kotlin con el fin de modelar tipos compuestos de una lista finita de valores.

Verás el uso del modificador enum, usar enumeraciones con la expresión when, importar las constantes para uso explícito y la definición de métodos y propiedades miembro en ellas.

Declaración De Clases enum En Kotlin

Al marcar una clase con el modificador enum, la declara como una de enumeración.

// Sintaxis
enum class Enumeracion{
    /* CONSTANTE1, CONSTANTE2, CONSTANTEN */
}

Una enumeración es un conjunto de valores que usan como identificador un nombre. Dicho nombre se comporta como una constante en nuestro lenguaje.

La forma más básica de uso en Kotlin, es el modelado de clases como un conjunto finito de valores distintos.

Por ejemplo, supón que necesitas definir los tipos de ítem de un juego que estás desarrollando, entre: Comunes, Raros y Legendarios.

enum class ItemType {
    NORMAL, RARE, LEGENDARY
}

La solución consiste en crear la clase enumerable ItemType y agregarle una instancia enumerable por cada tipo: NORMAL, RARE y LEGENDARY.

Usar Enumeraciones Con when

El mecanismo más común de interpretar los elementos de una enumeración en Kotlin, es a través de expresiones when.

Usas como argumento la instancia de tipo enumerable y luego estableces las constantes como ramas, donde determinas el valor de salida o bloque de código a ejecutar.

Por ejemplo, crea un método que retorne el tipo de ítem encontrado y luego imprime un mensaje informativo sobre dicho tipo.

fun getItemType(): ItemType {
    return ItemType.values().random()
}

fun main() {

    when (getItemType()) {
        ItemType.NORMAL -> println("Normal")
        ItemType.RARE -> println("Raro")
        ItemType.LEGENDARY -> println("Legendario")
    }
}

El método getItemType() simula la obtención del ítem usando el método values() de la enumeración.

Este obtiene un Array de las entradas enumerables. Y si usas la función random(), puedes obtener un valor aleatorio.

Importar Constantes De Enumeracion

Si quieres usar el nombre de las constantes de enumeración directamente, entonces importa explícitamente los valores con la gramática de alcance de clase (clase.*).

Por ejemplo, usamos directamente las entradas de ItemType con la importación ItemType.*:

import ItemType.*


fun getItemType(): ItemType {
    return ItemType.values().random()
}

fun main() {

    when (getItemType()) {
        NORMAL -> println("Normal")
        RARE -> println("Raro")
        LEGENDARY -> println("Legendario")
    }
}

En el caso de que requieras solo el uso de un identificador enumerable, entonces usas solo su dicho valor. Por ejemplo, para hacer explícito el uso de los ítems normales sería:

import ItemType.NORMAL

Enumeraciones Con Métodos Y Propiedades

También es posible la declaración de métodos y propiedades al interior de las clases enum en Kotlin.

Por ejemplo:

Se requiere añadir a la enumeración ItemType una propiedad que establezca la probabilidad de que aparezca un ítem de cada tipo.

También un método de utilidad que determine si un tipo de ítem cae o no, basado en su probabilidad.

enum class ItemType(val dropRate: Double) {
    NORMAL(0.5), RARE(0.2), LEGENDARY(0.1);

    fun itDrop(): Boolean {
        return Math.random() < dropRate
    }
}

La solución para la enum class se compuso de:

Acceder a las propiedades y funciones de cada constante se hace de forma regular:

val rate = ItemType.NORMAL.dropRate
val itDrop = ItemType.RARE.itDrop()

Por ejemplo:

Supón que tienes 1200 monedas de oro y el costo de un intento de obtener un objeto legendario es de 100 monedas.

Intenta la cantidad de veces necesarias mientras no sea arrojado un legendario y tengas oro:

fun main() {

    var gold = 1200
    var drop = false

    println("Oro inicial: $gold")
    print("Intentar conseguir ítem legendario")

    while (gold >= 100 && !drop) {
        val legendaryDrop = LEGENDARY.itDrop()
        print(".")
        if (legendaryDrop) {
            println("\n¡Encontraste un ítem legendario!")
            drop = true
        } else {
            gold -= 100
        }
    }
    if(!drop) println("¡Qué lástima!")
    println("Oro final:$gold")
}

La solución se basa en el retorno de LEGENDARY.itDrop(). Si es true, se finalizará el bucle while. Si es false, restas oro de tus arcas, hasta que ya no tengas el costo mínimo de 100 para otro intento.

La oportunidad de caída es del 10%, por lo que tomarán varios intentos en promedio. Al ejecutar la aplicación verás algo similar a esta salida:

Oro inicial: 1200
Intentar conseguir ítem legendario.......
¡Encontraste un ítem legendario!
Oro final:600
Salir de la versión móvil