Объектные выражения
Часть раздела Объектно-ориентированное программирование путешествия по Kotlin на Coddy. Урок 15 из 57.
Выражение объекта создаёт одноразовый объект безымянного класса именно там, где он нужен. Оно записывается как object : Type { ... } и обычно реализует интерфейс. Интерфейс перечисляет методы, не объясняя, как они работают; интерфейсы подробно рассматриваются в главе 5:
interface Greeter {
fun greet(name: String): String
}Внутри main:
val polite = object : Greeter {
override fun greet(name: String) = "Good morning, $name."
}
println(polite.greet("Ada"))Результат:
Good morning, Ada.Объявление объекта существует в единственном экземпляре. Выражение объекта вычисляется каждый раз, когда выполняется его код, и при каждом выполнении создаётся новый объект. Оно может читать локальные переменные вокруг себя и изменять их:
interface Counter {
fun next(): Int
}
fun counterFrom(start: Int): Counter {
var current = start
return object : Counter {
override fun next() = current++
}
}Внутри main:
val a = counterFrom(10)
val b = counterFrom(1)
println("${a.next()} ${a.next()} ${b.next()}")Результат:
10 11 1Один из распространённых вариантов использования — передать поведение функции библиотеки. sortedWith принимает Comparator — интерфейс, метод которого compare(a, b) возвращает отрицательное число, когда a должно идти первым, ноль при равенстве и положительное число в остальных случаях:
Внутри main:
val words = listOf("kiwi", "fig", "banana", "apple")
val byLength = object : Comparator<String> {
override fun compare(a: String, b: String) = a.length - b.length
}
println(words.sortedWith(byLength))Вывод:
[fig, kiwi, apple, banana]Объектное выражение без надтипа объединяет несколько значений в локальный объект; его свойства можно использовать внутри той же функции. Если у интерфейса есть единственный метод, лямбда часто короче объектного выражения. Объектные выражения подходят, когда есть несколько методов или требуется сохранить некоторое состояние.
val size = object {
val width = 3
val height = 4
}
println(size.width * size.height) // 12
val byLength = Comparator<String> { a, b -> a.length - b.length } // лямбда-формаЗадание
ЛегкоИнтерфейс Validator имеет один метод — check(text), который возвращает сообщение об ошибке или null, когда текст проходит проверку. Дополните функцию rules(minLength), чтобы она возвращала три валидатора, созданных с помощью объектных выражений, в следующем порядке: текст должен содержать как минимум minLength символов (too short), содержать цифру (needs a digit) и не содержать пробелов (no spaces allowed).
Предоставленный код считывает минимальную длину, а затем по одному паролю в каждой строке. Он выводит ok или все сообщения об ошибках этого пароля, объединённые с помощью ; .
Ваш код должен находиться в Rules.kt и Validator.kt. В Main.kt находится предоставленный код ввода/вывода, и его нельзя изменять.
Попробуйте сами
fun main() {
// Предоставленный код ввода/вывода: оставьте его как есть
val input = generateSequence(::readLine).toList()
val checks = rules(input[0].toInt())
for (password in input.drop(1)) {
val problems = checks.mapNotNull { it.check(password) }
println(if (problems.isEmpty()) "ok" else problems.joinToString("; "))
}
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
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