Spec-Zone.ru › Kotlin 1.7

Интерфейсы

Интерфейсы в 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()).

Последнее изменение: 02 июня 2022 г.
Свойства Функциональные (SAM) интерфейсы

© 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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API