web-dev-qa-db-fra.com

Objets compagnons dans les interfaces Kotlin

J'essaie de faire une interface Parcelable, en tant que telle j'ai besoin d'une interface comme celle-ci

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

et mes deux classes A et B ressemblant

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)
            }

        }
    }

J'ai du mal à implémenter une telle interface dans kotlin. Il semble que la classe d'interface ne permette pas le CREATOR

Peut-être que je prends la mauvaise approche,
J'ai une parcelle qui contient une liste de classes qui sont soit A soit B donc je fais

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

J'exige que la liste soit A ou B et c'est pourquoi j'utilise une interface.

Quelqu'un a-t-il des conseils ou une solution possible?

19
mickstar

Dans Kotlin, une interface peut avoir un companion object mais cela ne fait pas partie du contrat qui doit être implémenté par les classes qui implémentent l'interface. Il s'agit simplement d'un objet associé à l'interface qui possède une instance singleton. C'est donc un endroit où vous pouvez stocker des choses, mais cela ne signifie rien pour la classe d'implémentation.

Vous pouvez cependant avoir une interface implémentée par un companion object d'une classe. Peut-être que vous voulez quelque chose de plus comme ça:

interface Behavior {
   fun makeName(): String
}

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

Notez que la classe de données n'implémente pas l'interface, mais son companion object Est-ce que.

UNE companion object sur une interface serait utile pour stocker des constantes ou des fonctions d'assistance liées à l'interface, telles que:

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

Par convention les classes implémentant l'interface Parcelable doivent également avoir un champ statique non nul appelé CREATOR d'un type qui implémente le Parcelable.Creator interface.

Vous devez annoter la propriété CREATOR avec @JvmField annotation pour l'exposer en tant que champ statique public dans la classe de données contenant.

Vous pouvez également jeter un œil à https://github.com/grandstaish/paperparcel - un processeur d'annotation qui génère automatiquement des wrappers Parcelable de type sécurisé pour Kotlin et Java.

9
Ilya