Интерфейсы
Интерфейсы в 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–2023 JetBrains s.r.o. and Kotlin Programming Language contributors
Licensed under the Apache License, Version 2.0.
https://kotlinlang.org/docs/interfaces.html