Интерфейсы
Интерфейсы в 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()).
Генерация методов по умолчанию для функций интерфейсов в JVM
В JVM функции, объявленные в интерфейсах, компилируются в методы по умолчанию. Этим поведением можно управлять с помощью параметра компилятора -jvm-default, задавая одно из следующих значений:
enable(по умолчанию): генерирует реализации по умолчанию в интерфейсах и добавляет мостовые функции в подклассы и классыDefaultImpls. Используйте этот режим для сохранения двоичной совместимости с более ранними версиями Kotlin.no-compatibility: генерирует реализации по умолчанию только в интерфейсах. В этом режиме не создаются мосты совместимости и классыDefaultImpls, поэтому он подходит для нового кода на Kotlin.disable: пропускает методы по умолчанию и генерирует только мосты совместимости и классыDefaultImpls.
Чтобы настроить параметр компилятора -jvm-default, задайте свойство jvmDefault в Gradle Kotlin DSL:
kotlin {
compilerOptions {
jvmDefault = JvmDefaultMode.NO_COMPATIBILITY
}
}
© 2010–2026 JetBrains s.r.o. and Kotlin Programming Language contributors
Licensed under the Apache License, Version 2.0.
https://kotlinlang.org/docs/interfaces.html