Enum класи в Kotlin - це спеціальні класи для створення переліків (від англ. enumaration). Простий перелік Перелік видів старовинної зброї може виглядати так: enum class Weapon { SWORD, AXE, BOW } Кожен елемент переліку є константою і об'єктом, розмежовуються елементи при переліченні комами.
Ініціалізація констант Перелік може мати конструктор і ініціалізувати певні властивості для кожного елементу переліку. Наприклад додамо значення шкоди для кожного виду зброї: enum class Weapon (var damage:Int){ SWORD (15), AXE (20), BOW (16) } fun main(){ val weapon: Weapon = Weapon.AXE println(weapon.damage) // 20 println(Weapon.BOW.damage) // 16 } При потребі можна додавати кілька властивостей.
Визначення функцій у Enum класах Enum класи можуть містити також функції. Такі функції визначаються після переліку і крапки з комою: enum class Weapon (var damage:Int){ SWORD (15), AXE (20), BOW (16); fun getDescription():String{ return "Зброя:$this шкода:$damage"
fun main(){ val weapon=Weapon.AXE println(weapon.getDescription()) }
Властивості та функції Enum класів Всі переліки володіють двома властивостями name та ordinary. Перша властивість повертає ім'я переліку, друга порядковий номер переліку починаючи з нуля. enum class Weapon (var damage:Int){ SWORD (15), AXE (20), BOW (16) } fun main(){ val weapon1=Weapon.AXE println(weapon1.name) // AXE println(weapon1.ordinal) // 1 } Також, в Kotlin для Enum класу є додаткові функції: valueOf(value: String) - повертає об'єкт переліку по назві константи values() - повертає масив констант переліку
Замість функції values() можна скористатись властивістю EnumClass.entries: EnumEntries<EnumClass> // спеціалізований List<EnumClass> enum class Weapon (var damage:Int){ SWORD (15), AXE (20), BOW (16) } fun main() {
for(weapon in Weapon.values()) println("values(): "+weapon) for (weapon in Weapon.entries) println("Entries: "+weapon.toString()) val weapon2:Weapon=Weapon.valueOf("BOW") println("valueOf(): "+weapon2) }
Функція valueOf() викидає виняток IllegalArgumentException, якщо вказана назва не співпадає з константами переліку.
Анонімні класи Enum константи можуть декларувати свої власні анонімні класи із відповідними функціями та властивостями або заміщати (override) методи і властивості Enum класу: enum class Weapon (){ SWORD{ override val damage = 20 override fun getUkrName(): String { return "меч"
}, AXE{ override val damage = 25 override fun getUkrName(): String { return "сокира"
}, BOW{ override val damage = 11 override fun getUkrName(): String { return "лук"
abstract fun getUkrName():String abstract val damage:Int } fun main() { val weapon1 = Weapon.AXE val weapon2 = Weapon.BOW println("Зброя: ${weapon1.getUkrName()}, шкода: ${weapon1.damage}") println("Зброя: ${weapon2.getUkrName()}, шкода: ${weapon2.damage}") }
Реалізація інтерфейсів Enum класи також можуть реалізовувати інтерфейси: interface Printable { fun printInfo() }
enum class Weapon : Printable { SWORD { override fun printInfo() { println("меч")
}, AXE { override fun printInfo() { println("сокира")
}, BOW { override fun printInfo() { println("сокира")
fun main() { Weapon.AXE.printInfo() } Приклади програм із застосуванням переліку Наступна програма створює двох солдат, які б'ються між собою (почергову наносять собі удари) поки в одного з них не закінчиться здоров'я. При цьому кожен солдат отримує при створенні зброю із списку переліку Weapon. //перелік зброї enum class Weapon (val damage:Int, val ukrName:String){ SWORD(16, "меч"), AXE(20, "сокира"), BOW(14, "лук") }
//клас солдата class Soldier(var name:String, var health:Int, val weapon:Weapon)
//функція, яка реалізовує удар одного солдата іншим, //віднімається здоров'я у того солдата, якого вдарили fun hit(soldier: Soldier, hittedSoldier: Soldier){ println (soldier.name+" вдарив "+hittedSoldier.name) hittedSoldier.health=hittedSoldier.health-soldier.weapon.damage if (hittedSoldier.health<=0) println(hittedSoldier.name+" помер") } fun main() { val soldier1=Soldier("Adam", 100, Weapon.AXE) val soldier2=Soldier("Ren", 100, Weapon.SWORD)
//солдати б'ються почергово до смерті одного з них while ((soldier1.health>0)&&(soldier2.health>0)){ hit (soldier1, soldier2) if (soldier2.health>0)hit (soldier2, soldier1)
Часто необхідно зробити певну дію в програмі, в залежності від певної константи переліку. Тоді можна перебрати константи з допомогою конструкції when. Наступний приклад демонструє присвоєння класу солдату (піхотинець або лучник) в залежності від його зброї: enum class Weapon (val damage:Int, val ukrName:String){ SWORD(16, "меч"), AXE(20, "сокира"), BOW(14, "лук") }
class Soldier(var name:String, var health:Int, val weapon:Weapon){ fun getClass():String{ return when(weapon){ Weapon.SWORD->"піхотинець" Weapon.AXE->"піхотинець" Weapon.BOW->"лучник"
fun main() { val soldier1=Soldier("Adam", 100, Weapon.AXE) val soldier2=Soldier("Ren", 100, Weapon.SWORD) println("${soldier1.name} - ${soldier1.getClass()}") println("${soldier2.name} - ${soldier2.getClass()}") }
В конструкції when необхідно перерахувати усі можливі випадки переліку або застосувати else.