Spec-Zone.ru › Kotlin 1.8

Интерфейсы

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

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

© 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

Spec-Zone.ru

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