Объявление интерфейсов
Часть раздела Объектно-ориентированное программирование путешествия по Kotlin на Coddy. Урок 22 из 57.
Интерфейс перечисляет, что тип умеет делать, не объясняя как. Он объявляет методы и свойства, которые должен предоставлять каждый реализующий его класс. Класс реализует интерфейс с помощью двоеточия, как и суперкласс, но без скобок, поскольку у интерфейса нет конструктора:
interface Drawable {
fun draw(): String
}
class Circle(val radius: Int) : Drawable {
override fun draw() = "circle with radius $radius"
}
class Line(val length: Int) : Drawable {
override fun draw() = "-".repeat(length)
}Внутри main:
println(Circle(3).draw())
println(Line(5).draw())Вывод:
circle with radius 3
-----Интерфейс также может объявлять свойства. Класс предоставляет их как свойства конструктора, хранимые свойства или геттеры; сам интерфейс ничего не хранит:
interface Vehicle {
val wheels: Int
val label: String
}
class Car(override val label: String) : Vehicle {
override val wheels = 4
}
class Bike : Vehicle {
override val wheels = 2
override val label: String
get() = "bike on $wheels wheels"
}Внутри main:
println("${Car("taxi").label}: ${Car("taxi").wheels}")
println(Bike().label)Результат:
taxi: 4
bike on 2 wheelsКаждый член, объявленный интерфейсом, должен быть реализован, причём для каждого из них необходимо указать override, иначе класс не скомпилируется. Экземпляр интерфейса создать нельзя:
interface Speaker {
fun speak(): String
val volume: Int
}
// class Mute : Speaker { override fun speak() = "" } // ошибка: volume не реализован
// class Loud : Speaker() { ... } // ошибка: у интерфейса нет конструктора
// val s = Speaker() // ошибка: нельзя создать интерфейсИнтерфейс и абстрактный класс объявляют члены без тела. У интерфейса нет конструктора и сохранённого состояния, а класс может реализовывать множество интерфейсов, но расширять только один класс. Используй интерфейс для возможности, общей для несвязанных классов, например Drawable или Comparable, а абстрактный класс — для общего базового класса с состоянием.
interface Drawable { fun draw(): String } // возможность
abstract class Shape(val name: String) { abstract fun area(): Double } // база с состоянием
class Square(val s: Double) : Shape("square"), Drawable { // один класс, любые интерфейсы
override fun area() = s * s
override fun draw() = "[]"
}Задание
ЛегкоОбъяви члены интерфейса Shape: свойство только для чтения name и методы area() и perimeter(), оба возвращающие Double. Реализуй их в Rectangle(width, height) (имя rectangle) и Circle(radius) (имя circle, с использованием Math.PI). Затем дополни describe(shape), которая возвращает rectangle: area 12.00, perimeter 14.00 с двумя десятичными знаками, используя только члены Shape.
Предоставленный код считывает строки r,3,4 или c,2, создаёт соответствующую фигуру и выводит describe(shape).
Твой код должен находиться в Shape.kt, Rectangle.kt, Circle.kt и Functions.kt. В Main.kt находится предоставленный код ввода-вывода, и его нельзя редактировать.
Попробуйте сами
fun main() {
// Предоставленный код ввода/вывода: оставьте его как есть
val input = generateSequence(::readLine).toList()
for (line in input) {
val p = line.split(",").map { it.trim() }
val shape: Shape = if (p[0] == "r") Rectangle(p[1].toDouble(), p[2].toDouble()) else Circle(p[1].toDouble())
println(describe(shape))
}
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
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