Интерфейсы
Интерфейсы в Kotlin могут содержать объявления абстрактных методов, а также реализации методов. Отличие их от абстрактных классов заключается в том, что интерфейсы не могут хранить состояние. Они могут иметь свойства, но эти свойства должны быть абстрактными или предоставлять реализации аксессоров.
Интерфейс определяется с помощью ключевого слова interface:
interface MyInterface {
fun bar()
fun foo() {
// optional body
}
}
Реализация интерфейсов
Класс или объект могут реализовывать один или несколько интерфейсов:
class Child : MyInterface {
override fun bar() {
// body
}
}
Свойства в интерфейсах
Вы можете объявлять свойства в интерфейсах. Свойство, объявленное в интерфейсе, может быть абстрактным или предоставлять реализации аксессоров. Объявленные в интерфейсах свойства не могут иметь свойств backing, поэтому аксессоры, объявленные в интерфейсах, не могут ссылаться на них:
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