web-dev-qa-db-ja.com

Kotlinインターフェースのコンパニオンオブジェクト

インターフェースをParcelableにしようとしているため、このようなインターフェースが必要です。

interface AB : Parcelable {
    companion object {
        val CREATOR : Parcelable.Creator<AB>
    }
}

私の2つのクラスAとBは

data class A (...): Parcelable{
    ...
    companion object {
        val CREATOR : Parcelable.Creator<AB> = object : Parcelable.Creator<AB> {
            override fun newArray(size: Int): Array<AB?> {
                return arrayOfNulls(size)
            }

            override fun createFromParcel(parcel: Parcel): AB {
                return A(parcel)
            }

        }
    }

そのようなインターフェイスをkotlinに実装するのに苦労しています。インターフェースクラスがCREATORを許可していないようです

多分私は間違ったアプローチをとっています、
AまたはBのいずれかのクラスのリストを含む小包があります。

parcel.readTypedList(this.list, AB.CREATOR)

リストはAまたはBのいずれかである必要があるため、インターフェースを使用しています。

誰かアドバイスや解決策はありますか?

19
mickstar

Kotlinでは、インターフェイスに companion object を含めることができますが、インターフェイスを実装するクラスによって実装する必要があるコントラクトの一部ではありません。これは、1つのシングルトンインスタンスを持つ、インターフェイスに関連付けられたオブジェクトです。つまり、物事を保存できる場所ですが、実装クラスにとっては何の意味もありません。

ただし、クラスのcompanion objectによって実装されるインターフェースを持つことはできます。多分あなたはこのようなものをもっと欲しがります:

interface Behavior {
   fun makeName(): String
}

data class MyData(val data: String) {
    companion object: Behavior {  // interface used here
        override fun makeName(): String = "Fred"
    }
}

データクラスはインターフェースを実装していませんが、そのcompanion objectは実装しています。

インターフェイスのcompanion objectは、次のような、インターフェイスに関連する定数またはヘルパー関数を格納するのに役立ちます。

interface Redirector {
    fun redirectView(newView: String, redirectCode: Int)

    companion object {
        val REDIRECT_WITH_FOCUS = 5
        val REDIRECT_SILENT = 1
    }
}

// which then can be accessed as:
val code = Redirector.REDIRECT_WITH_FOCUS
30
Jayson Minard

規約Parcelableインターフェースを実装するクラスには、Parcelable.Creatorインターフェースを実装する型のCREATORと呼ばれるnull以外の静的フィールドも必要です。

含まれているデータクラスのパブリック静的フィールドとして公開するには、CREATORプロパティに@JvmFieldアノテーションを付ける必要があります。

https://github.com/grandstaish/paperparcel — KotlinおよびJava用のタイプセーフなParcelableラッパーを自動的に生成するアノテーションプロセッサもご覧ください。

9
Ilya