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

Kotlin 接口(Interface)

In questo articolo, imparerai grazie a esempi tutto ciò che c'è da sapere sulle interfacce e su come implementare un'interfaccia in Kotlin.

Le interfacce Kotlin sono simili alle interfacce di Java 8. Possono contenere definizioni di metodi astratti e implementazioni di metodi non astratti. Ma non possono contenere alcun stato.

Quindi, un'interfaccia può avere proprietà, ma devono essere astratte o devono fornire implementazioni degli accessori.

Leggi anche: Kotlin Classi Astratte

In Kotlin, le classi astratte sono simili alle interfacce, ma c'è una distinzione importante. Le proprietà delle classi astratte non devono essere astratte o fornire implementazioni degli accessori.

Come si definisce un'interfaccia?

La parola chiave interface viene utilizzata per definire un'interfaccia in Kotlin. Ad esempio,

interface MyInterface {
    var test: String //Proprietà astratta
    fun foo() //Metodo astratto
    fun hello() = "Hello there" //Metodo con implementazione predefinita
}

Qui,

  • Creare l'interfaccia MyInterface.

  • L'interfaccia ha una proprietà astratta test e un metodo astratto foo().

  • L'interfaccia ha anche un metodo non astratto hello().

Come si implementa un'interfaccia?

Ecco come una classe o un oggetto implementa un'interfaccia:

interface MyInterface {
    val test: Int //Proprietà astratta
    fun foo(): String //Metodo astratto (ritorna una stringa)
    fun hello() { //Metodo con implementazione predefinita
        //body (opzionale)
    }
}
class InterfaceImp: MyInterface {
    override val test: Int = 25
    override fun foo() = "Lol"
    //Altri codici
}

Qui, la classe InterfaceImp implementa l'interfaccia MyInterface.

Questa classe sovrascrive i membri astratti dell'interfaccia (proprietà test e metodo foo()).

Esempio: come funziona l'interfaccia?

interface MyInterface {
    val test: Int
    fun foo(): String
    fun hello() {
        println("Ciao, amico!")
    }
}
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("Chiamata a hello():")
    obj.hello()
    print("Chiamata e stampa foo(): ")
    println(obj.foo())
}

Quando si esegue il programma, l'output è:

test = 25
Chiamata hello(): Buongiorno, amico!
Chiamata e stampa foo(): Lol

Come già detto, un'interfaccia può avere proprietà che forniscono un'implementazione degli accessori. Ad esempio:

interface MyInterface {
    // Proprietà con implementazione
    val prop: Int
        get() = 23
}
class InterfaceImp: MyInterface {
    // Corpo della classe
}
fun main(args: Array<String>) {
    val obj = InterfaceImp()
    println(obj.prop)
}

Quando si esegue il programma, l'output è:

23

Qui, prop non è astratto, ma è valido nell'interfaccia perché fornisce un'implementazione dell'accessore.

Tuttavia, non è possibile eseguire operazioni come val prop: Int = 23 all'interno di un'interfaccia.

Implementazione di due o più interfacce in una classe

Kotlin non consente un vero multiplo ereditaggio. Tuttavia, è possibile implementare due o più interfacce in una classe. Ad esempio:

interface A {
    fun callMe() {
        println("Da interfaccia A")
    }
}
interface B {
    fun callMeToo() {
        println("Da interfaccia B")
    }
}
// Implementazione delle interfacce A e B
class Child: A, B
fun main(args: Array<String>) {
    val obj = Child()
    obj.callMe()
    obj.callMeToo()
}

Quando si esegue il programma, l'output è:

Da interfaccia A
Da interfaccia B

Risoluzione conflitto di sovrascrittura (multi-interfaccia)

Supponiamo che due interfacce (A e B) abbiano metodi non astratti con lo stesso nome (ad esempio, il metodo callMe()). Implementi queste interfacce in una classe (ad esempio, C). Ora, se si utilizza un oggetto della classe C per chiamare il metodo callMe(), il compilatore genererà un errore. Esempio

interface A {
    fun callMe() {
        println("interfaccia A")
    }
}
interface B {
    fun callMe() {
        println("interfaccia B")
    }
}
class Child: A, B 
fun main(args: Array<String>) {
    val obj = Child()
    obj.callMe()
}

Questo è l'errore lanciato:

Error:(14, 1) Kotlin: La classe 'C' deve sovrascrivere il metodo pubblico aperto fun callMe(): Unit definito in A perché eredita più metodi di interfaccia di essa

Per risolvere questo problema, devi fornire la tua implementazione. Ecco come fare:

interface A {
    fun callMe() {
        println("interfaccia A")
    }
}
interface B {
    fun callMe() {
        println("interfaccia 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() 調用類 A 的 callMe() 方法。類似地,super<B>.callMe() 調用類 B 的 callMe() 方法。