Множественные интерфейсы
Часть раздела Объектно-ориентированное программирование путешествия по Kotlin на Coddy. Урок 24 из 57.
Класс может реализовывать несколько интерфейсов, разделённых запятыми. Он должен реализовать члены всех этих интерфейсов:
interface Switchable {
var isOn: Boolean
fun toggle() { isOn = !isOn }
}
interface Dimmable {
var level: Int
}
class Lamp : Switchable, Dimmable {
override var isOn = false
override var level = 100
}Внутри main:
val lamp = Lamp()
lamp.toggle()
lamp.level = 40
println("${lamp.isOn} ${lamp.level}")Вывод:
true 40Класс может расширять один класс и реализовывать интерфейсы в одном заголовке. Только у суперкласса есть вызов конструктора:
open class Device(val name: String)
interface Rechargeable {
fun charge(): String
}
class Phone(name: String) : Device(name), Rechargeable {
override fun charge() = "$name is charging"
}Внутри main:
println(Phone("Pixel").charge())Вывод:
Pixel is chargingЕсли два интерфейса предоставляют один и тот же метод с реализацией по умолчанию, класс должен переопределить его и решить, что делать. super<Name>.method() вызывает версию определённого интерфейса:
interface Camera {
fun describe() = "takes photos"
}
interface Telephone {
fun describe() = "makes calls"
}
class SmartPhone : Camera, Telephone {
override fun describe() = super<Telephone>.describe() + " and " + super<Camera>.describe()
}Внутри main:
println(SmartPhone().describe())Вывод:
makes calls and takes photosИнтерфейс может расширять другие интерфейсы. Класс, реализующий объединённый интерфейс, должен предоставить члены всех этих интерфейсов, и он считается каждым из них:
interface Named {
val name: String
}
interface Contact : Named {
val email: String
fun card() = "$name <$email>"
}
class Person(override val name: String, override val email: String) : ContactВнутри main:
val ada = Person("Ada", "ada@example.com")
val named: Named = ada
println(ada.card())
println(named.name)Вывод:
Ada <ada@example.com>
AdaЗадание
ЛегкоДва интерфейса описывают умное устройство: Switchable требует наличия isOn (доступного вызывающему коду только для чтения Boolean) и toggle(), а Dimmable требует доступного для записи brightness. Сделайте так, чтобы SmartLamp реализовывал оба интерфейса: изначально он выключен, а яркость равна 100; toggle() переключает его между включённым и выключенным состоянием; значение яркости вне диапазона от 0 до 100 ограничивается сеттером; status() возвращает on 70% или off.
Предоставленный код считывает команды toggle или число яркости, применяет их к одной лампе и после каждой команды выводит status(), а затем проверяет, что лампа является Switchable и Dimmable.
Ваш код должен находиться в файлах Switchable.kt, Dimmable.kt и SmartLamp.kt. В Main.kt находится предоставленный код ввода-вывода, и его нельзя изменять.
Попробуйте сами
fun main() {
// Предоставленный код ввода/вывода: оставьте его как есть
val input = generateSequence(::readLine).toList()
val lamp = SmartLamp()
for (cmd in input) {
if (cmd == "toggle") lamp.toggle() else lamp.brightness = cmd.toInt()
println(lamp.status())
}
println("switchable: ${(lamp as Any) is Switchable}, dimmable: ${(lamp as Any) is Dimmable}")
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
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