Интерфейсы
Интерфейсы в Kotlin могут содержать объявления абстрактных методов, а также реализации методов. Отличием их от абстрактных классов является то, что интерфейсы не могут хранить состояние. Они могут иметь свойства, но эти свойства должны быть абстрактными или предоставлять реализации аксессоров.
Интерфейс определяется с помощью ключевого слова interface.
interface MyInterface {
fun bar()
fun foo() {
// optional body
}
}
Реализация интерфейсов
Класс или объект может реализовывать один или несколько интерфейсов:
class Child : MyInterface {
override fun bar() {
// body
}
}
Свойства в интерфейсах
Вы можете объявлять свойства в интерфейсах. Свойство, объявленное в интерфейсе, может быть либо абстрактным, либо предоставлять реализации аксессоров. Объявленные в интерфейсах свойства не могут иметь полей-хранилищ, и поэтому аксессоры, объявленные в интерфейсах, не могут ссылаться на них:
interface MyInterface {
val prop: Int // abstract
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(
// implementing 'name' is not required
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 реализует bar() (bar() не помечена как абстрактная в A, потому что это значение по умолчанию для интерфейсов, если функция не имеет тела). Теперь, если вы выведите конкретный класс C из A, вам нужно будет переопределить bar() и предоставить реализацию.
Однако, если вы выведете D из A и B, вам нужно будет реализовать все методы, которые вы унаследовали от нескольких интерфейсов, и вам нужно будет указать, как именно D должен их реализовать. Это правило относится как к методам, для которых вы унаследовали одну реализацию (bar()), так и к тем, для которых вы унаследовали несколько реализаций (foo()).
© 2010–2022 JetBrains s.r.o. and Kotlin Programming Language contributors
Licensed under the Apache License, Version 2.0.
https://kotlinlang.org/docs/interfaces.html