Классы перечислений
Часть раздела Объектно-ориентированное программирование путешествия по Kotlin на Coddy. Урок 33 из 57.
enum class объявляет тип с фиксированным набором значений — его константами. Каждая константа является объектом перечисления с name и ordinal — её позицией, начинающейся с 0. 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 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Для 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 мл, цена 300), MEDIUM (350 мл, 380) и LARGE (500 мл, 450); цены указаны в центах. label() возвращает medium (350 ml): 3.80, а upsize() возвращает следующий больший размер или тот же размер для LARGE. parse(text) companion-объекта находит размер по его имени без учёта регистра или по его первой букве (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))
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Классы и объекты
Работа с файламиОпределение классовПервичные конструкторыБлоки init и валидацияВторичные конструкторыПовторение — читательский билет4Наследование
Открытые классы и подклассыПереопределение членовsuper и конструкторыАбстрактные классыПовторение — каталог сотрудников7Специальные классы
Классы данныхКлассы перечисленийЗапечатанные иерархииequals, hashCode, toStringПовторение — трекер заказов10Паттерны проектирования. Часть 2
Делегирование с помощью byПаттерн декораторПаттерн строительПаттерн состояние2Свойства и инкапсуляция
Пользовательские аксессорыМодификаторы видимостиПриватные сеттерыlazy и lateinitПовторение — банковский счёт5Интерфейсы
Объявление интерфейсовМетоды по умолчаниюМножественные интерфейсыИнтерфейсы как типыПовторение — способы оплаты8Обобщения
Обобщённые функцииОбобщённые классыОграничения типовВариативность с in и outПовторение — очередь с приоритетом11Проект: Управление библиотекой
Книги и читателиВыдача книг3Объекты и компаньоны
Объявления объектовОбъекты-компаньоныКонстанты с constОбъектные выраженияПовторение — билетная касса6Полиморфизм
Динамическая диспетчеризацияПроверка типов и умные приведения типовwhen с типамиФункции-расширенияПовторение — смотритель зоопарка9Паттерны проектирования. Часть 1
Паттерн «Одиночка»Фабричный паттернПаттерн «Наблюдатель»Паттерн «Стратегия»Потренируйтесь самостоятельно: Песочница Kotlin