Блоки init и валидация
Часть раздела Объектно-ориентированное программирование путешествия по Kotlin на Coddy. Урок 4 из 57.
Блок init выполняется при создании экземпляра сразу после присваивания параметров конструктора. Он предназначен для кода настройки, который не помещается в одно объявление свойства:
class Order(val id: Int, items: List<Int>) {
val total: Int
val count: Int
init {
total = items.sum()
count = items.size
println("created order $id")
}
}Внутри main:
val o = Order(7, listOf(4, 6, 10))
println("${o.count} items, total ${o.total}")Вывод:
created order 7
3 items, total 20require(condition) { message } проверяет аргумент и выбрасывает IllegalArgumentException с сообщением, когда условие ложно. Размещение этого вызова в init означает, что недопустимый экземпляр никогда не может быть создан:
class Percentage(val value: Int) {
init {
require(value in 0..100) { "percentage must be 0-100, was $value" }
}
}Внутри main:
println(Percentage(42).value)
try {
Percentage(150)
} catch (e: IllegalArgumentException) {
println(e.message)
}Вывод:
42
percentage must be 0-100, was 150У класса может быть несколько блоков init; они выполняются по порядку вместе с инициализаторами свойств, сверху вниз:
class Demo(name: String) {
val first = "first: $name".also { println(it) }
init { println("init 1") }
val second = "second".also { println(it) }
init { println("init 2") }
}Внутри main:
Demo("x")
println("done")Вывод:
first: x
init 1
second
init 2
doneПроверка в init размещает правило рядом с данными. Код, получающий экземпляр, может доверять ему и не проверять его снова:
class Email(val address: String) {
init {
require("@" in address) { "not an email: $address" }
}
}
fun send(to: Email) { /* нет необходимости снова проверять адрес */ }Задание
ЛегкоЗавершите класс Password. Его блок init с помощью require проверяет, что текст содержит как минимум 8 символов (сообщение too short) и содержит цифру (сообщение needs a digit), именно в таком порядке. Свойство strength вычисляется в init: strong, если текст также содержит заглавную букву, и ok в противном случае.
Предоставленный код создаёт объект Password для каждой входной строки и выводит strength или сообщение об ошибке.
Ваш код должен находиться в Password.kt. В Main.kt содержится предоставленный код ввода/вывода, и его нельзя редактировать.
Попробуйте сами
fun main() {
// Предоставленный код ввода/вывода: оставьте его как есть
val input = generateSequence(::readLine).toList()
for (line in input) {
try {
println(Password(line).strength)
} catch (e: IllegalArgumentException) {
println(e.message)
}
}
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
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