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

Kotlin インターフェース(Interface)

この記事では、サンプルを用いてインターフェースおよびKotlinでインターフェースを実装する方法について学びます。

KotlinインターフェースはJavaに似ています 8のインターフェース。それらは抽象メソッドの定義と非抽象メソッドの実装を含むことができますが、状態を含むことはできません。

つまり、インターフェースには属性がありますが、それ必须是抽象的であるか、アクセッサーの実装を提供する必要があります。

おすすめの読書: Kotlin 抽象クラス

Kotlinの抽象クラスはインターフェースに似ていますが、重要な違いがあります。抽象クラスの属性は抽象的である必要はなく、アクセッサーの実装を提供する必要もありません。

インターフェースを定義する方法はどうですか?

キーワードinterfaceはKotlinでインターフェースを定義するために使用されます。例えば、

interface MyInterface {
    var test: String   //抽象属性
    fun foo()          //抽象メソッド
    fun hello() = "Hello there" //デフォルトの実装を持つメソッド
}

ここでは、

  • インターフェースMyInterfaceを作成します。

  • このインターフェースには、抽象属性testと抽象メソッドfoo()があります。

  • このインターフェースには、非抽象メソッドhello()もあります。

インターフェースを実装する方法はどうですか?

これはクラスやオブジェクトがインターフェースを実装する方法です:

interface MyInterface {
    val test: Int   //抽象属性
    fun foo() : String   //抽象メソッド(文字列を返す)
    fun hello() {   //デフォルトの実装を持つメソッド
        // 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("テスト = ${obj.test}"}
    print("hello(): ")
    obj.hello()
    print("foo(): Lolを呼び出し、表示する")
    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 の操作を行います。

クラスの中で2つまたは複数のインターフェースを実装する

Kotlinでは実際の多重継承は許可されていませんが、クラスの中で2つまたは複数のインターフェースを実装することができます。例えば、

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)を実装しています。今、C クラスのオブジェクトを使用して callMe() メソッドを呼び出した場合、コンパイラがエラーを引き起こします。例えば

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: Class 'C' は、A から複数のインターフェースメソッドを継承しているため、public open fun callMe(): Unit をオーバーライドする必要があります

この問題を解決するには、あなた自身の実装を提供する必要があります。以下のようにします:

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() はクラス A の callMe() メソッドを呼び出します。同様に、super<B>.callMe() はクラス B の callMe() メソッドを呼び出します。