Интерфейсы
Интерфейсы в Kotlin очень похожи на Java 8. Они могут содержать объявление абстрактных методов, а также реализации методов. Что отличает их от абстрактных классов, так это то, что интерфейсы не могут хранить состояние. У интерфейсов могут быть свойства, но они должны быть абстрактными или предоставлять реализацию аксессоров.
Интерфейс в Kotlin языке определяется с использованием ключевого слова interface
interface MyInterface {
fun bar()
fun foo() {
// тело функции опционально
}
}
Реализация интерфейсов
Класс или объект может реализовать один или несколько интерфейсов
class Child : MyInterface {
override fun bar() {
// тело функции
}
}
Свойства в интерфейсах
Вы можете объявлять свойства в интерфейсах. Свойство объявленое в интерфейсе может быть либо абстрактным, либо предоставлять реализацию для аксессоров. Свойстваа объявленные в интерфейсах не могут иметь backing полей, поэтому аксессор методы не могут ссылаться на них.
interface MyInterface {
val prop: Int // абстрактное
val propertyWithImplementation: String
get() = "foo"
fun foo() {
print(prop)
}
}
class Child : MyInterface {
override val prop: Int = 29
}
Наследование интерфейсов
Интерфейс может наследоваться от другого интерфейса, таким образом предоставляя реализацию их членов и описывая новые функции и свойства. Естественно, классы реализующие такой интерфейс должны определить недостающие реализации.
interface Named {
val name: String
}
interface Person : Named {
val firstName: String
val lastName: String
override val name: String get() = "$firstName $lastName"
}
data class Employee(
// реализация 'name' не обязательна
override val firstName: String,
override val lastName: String,
val position: Position
) : Person
Разрешение конфликтов переопределения
Когда мы объявляем много типов в нашем списке супертипов, может показаться, что мы наследуем более одной реализации того же метода как показано на примере ниже:
interface A {
fun foo() { print("A") }
fun bar()
}
interface B {
fun foo() { print("B") }
fun bar() { print("bar") }
}
class C : A {
override fun bar() { print("bar") }
}
class D : A, B {
override fun foo() {
super<A>.foo()
super<B>.foo()
}
override fun bar() {
super<B>.bar()
}
}
Интерефейсы A и B оба объяляют функции foo() и bar().
Оба интерфейса реализуют foo(), но только B реализуется foo() и bar()
(bar() не помечен абстрактным в A, потому что это является по умолчанию для интерфейсов, если функция не имеет тела).
Теперь, если мы наследуем конкретный класс C от A, очевидно мы должны переопределить bar() и предоставить реализацию.
Однако, если мы наследуем D от A и B, мы должны реализовать все метды нескольких интерфейсов и указать как именно D будет их реализовать. Это правило в Kotlin применяется как к функциям унаследованным с одной реализацией, так и к фукнциям со множественной реализацией.
Комментарии
Отправить комментарий