English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Основы Kotlin

Flow Control Kotlin

Функции в Kotlin

Строки в Kotlin

Оriented Object Programming (OOP) Kotlin

Интерфейсы (Interface) в Kotlin

В этой статье вы узнаете о интерфейсах и о том, как реализовать интерфейсы в Kotlin с помощью примеров.

Интерфейсы Kotlin подобны интерфейсам Java 8. Они могут содержать определения абстрактных методов и реализацию неабстрактных методов. Но они не могут содержать никакого состояния.

То есть, интерфейс может иметь свойства, но они должны быть абстрактными или должны предоставлять реализацию доступа.

Рекомендуем к прочтению: Абстрактный класс Kotlin

Абстрактный класс в Kotlin подобен интерфейсу, но есть важное различие. Свойства абстрактного класса не должны быть абстрактными или предоставлять реализацию доступа.

Как определить интерфейс?

Ключевое слово interface используется для определения интерфейса в Kotlin. Например,

interface MyInterface {
    var test: String //Абстрактное свойство
    fun foo()  //Абстрактный метод
    fun hello() = "Hello there" //Метод с_default_исполнением
{}

Здесь,

  • Создайте интерфейс MyInterface.

  • Этот интерфейс имеет абстрактное свойство test и абстрактный метод foo().

  • Этот интерфейс также имеет неабстрактный метод hello().

Как реализовать интерфейс?

Вот как класс или объект реализует метод интерфейса:

interface MyInterface {
    val test: Int //Абстрактное свойство
    fun foo() : String //Абстрактный метод (возвращает строку)
    fun hello() { //Метод с_default_исполнением
        // body (необязательное)
    {}
{}
class InterfaceImp: MyInterface {
    override val test: Int = 25
    override fun foo() = "Lol"
    //Другой код
{}

Здесь, класс InterfaceImp реализует интерфейс MyInterface.

Этот класс переопределяет абстрактные члены интерфейса (свойство test и метод foo()).

Пример: как работает интерфейс?

interface MyInterface {
    val test: Int
    fun foo() : String
    fun hello() {
        println("你好,伙计!")
    {}
{}
class InterfaceImp: MyInterface {
    override val test: Int = 25
    override fun foo() = "Lol"
{}
fun main(args: Array<String>) {
    val obj = InterfaceImp()
    println("test = ${obj.test}")
    print("Вызов hello():")
    obj.hello()
    print("Вызов и печать foo(): ")
    println(obj.foo())
{}

При выполнении программы выводится:

test = 25
Вызов hello(): Привет, парень!
Вызов и печать foo(): Lol

Как уже говорилось, интерфейсы могут иметь свойства с предоставленной реализацией доступа. Например,

interface MyInterface {
    // Свойства с реализацией
    val prop: Int
        get() = 23
{}
class InterfaceImp: MyInterface {
    // Основной класс
{}
fun main(args: Array<String>) {
    val obj = InterfaceImp()
    println(obj.prop)
{}

При выполнении программы выводится:

23

Здесь, prop не абстрактный, но он является эффективным в интерфейсе, потому что он предоставляет реализацию доступа.

Но вы не можете выполнять действия, такие как val prop: Int = 23 в интерфейсе.

Реализация двух или более интерфейсов в одном классе

Kotlin не позволяет истинное множественное наследование. Однако, можно реализовать два или более интерфейсов в одном классе. Например,

interface A {
    fun callMe() {
        println("Из интерфейса A")
    {}
{}
interface B {
    fun callMeToo() {
        println("Из интерфейса B")
    {}
{}
// Реализация двух интерфейсов A и B
class Child: A, B
fun main(args: Array<String>) {
    val obj = Child()
    obj.callMe()
    obj.callMeToo()
{}

При выполнении программы выводится:

Из интерфейса A
Из интерфейса B

Решение конфликта переопределения (множественные интерфейсы)

Предположим, что два интерфейса (A и B) имеют методы с одинаковыми именами (например, callMe()). Вы реализуете这两个 интерфейсы в одном классе (например, C). Теперь, если вызвать метод callMe() через объект класса C, компилятор выдаст ошибку. Например

interface A {
    fun callMe() {
        println("Интерфейс A")
    {}
{}
interface B {
    fun callMe() {
        println("Интерфейс B")
    {}
{}
class Child: A, B 
fun main(args: Array<String>) {
    val obj = Child()
    obj.callMe()
{}

Вот ошибка, которая возникает:

Error:(14, 1) Kotlin: Класс 'C' должен переопределить public open fun callMe(): Unit, определенный в A, потому что он наследует несколько методов интерфейса A

Чтобы решить эту проблему, вам нужно предоставить свою реализацию. Вот как это делается:

interface A {
    fun callMe() {
        println("Интерфейс A")
    {}
{}
interface B {
    fun callMe() {
        println("Интерфейс B")
    {}
{}
class C: A, B {
    override fun callMe() {
        super<A>.callMe()
        super<B>.callMe()
    {}
{}
fun main(args: Array<String>) {
    val obj = C()
    obj.callMe()
{}

Теперь, когда вы запустите программу, вывод будет:

Интерфейс A
Интерфейс B

Здесь, в классе C предоставляется явное реализация метода callMe().

class C: A, B {
    override fun callMe() {
        super<A>.callMe()
        super<B>.callMe()
    {}
{}

Указание super<A>.callMe() вызывает метод callMe() класса A. Аналогично, super<B>.callMe() вызывает метод callMe() класса B.