web-dev-qa-db-fra.com

Pourquoi utilisons-nous "objet compagnon" comme une sorte de remplacement des champs statiques Java dans Kotlin?

Quelle est la signification de "objet de compagnon"? Jusqu'ici, je ne l'ai utilisé que pour remplacer la static de Java lorsque j'en ai besoin. 

Je suis confondu avec:

  • Pourquoi s'appelle-t-il "compagnon"?
  • Est-ce que cela signifie que pour créer plusieurs propriétés static, je dois les regrouper dans un bloc companion object?
  • Pour créer instantanément une instance de singleton étendue à une classe, j'écris souvent

:

companion object {
    val singleton by lazy { ... }
}

ce qui semble être une façon unidiomatique de le faire. Quel est le meilleur moyen?

119
  • Quelle est la signification de "objet de compagnon"? Pourquoi s'appelle-t-il "compagnon"?

    Tout d'abord, Kotlin n'utilise pas le concept Java de static membres car Kotlin a son propre concept de objects pour décrire les propriétés et les fonctions liées à l'état singleton, et Java static une partie d'une classe peut être élégamment exprimée en singleton. : c'est un objet singleton qui peut être appelé par le nom de la classe. D'où le nommage: c'est un objet qui vient avec une classe.

    Son nom était class object ET default object , mais il a été renommé en companion object , ce qui est plus clair et correspond également aux objets compagnons Scala .

    En plus de la dénomination, il est plus puissant que les membres static de Java: il peut étendre les classes et les interfaces, et vous pouvez le référencer et le transmettre comme d'autres objets.

  • Est-ce que cela signifie que pour créer plusieurs propriétés statiques, je dois les regrouper dans un bloc companion object?

    Oui, c'est la façon idiomatique. Ou vous pouvez même les regrouper dans des objets non compagnons par leur signification:

    class MyClass {
        object IO {
            fun makeSomethingWithIO() { /* ... */ }
        }
    
        object Factory {
            fun createSomething() { /* ... */ }
        }
    }
    
  • Pour créer instantanément une instance de singleton étendue à une classe, j'écris souvent /*...*/, ce qui semble être une façon unidiomatique de le faire. Quel est le meilleur moyen?

    Cela dépend de ce dont vous avez besoin dans chaque cas particulier. Votre code convient bien pour stocker l’état lié à une classe qui est initialisée lors de son premier appel.

    Si vous n'avez pas besoin qu'elle soit connectée à une classe, utilisez simplement la déclaration d'objet:

    object Foo {
        val something by lazy { ... }
    }
    

    Vous pouvez également supprimer lazy { ... } delegation pour que la propriété soit initialisée à l'usage de la première classe, comme pour les initialiseurs statiques Java.

    Vous pouvez également trouver des méthodes utiles pour initialiser singleton state .

85
hotkey

Pourquoi s'appelle-t-il "compagnon"?

Cet objet est un compagnon des instances . IIRC il y avait une longue discussion ici: Prochaine-changement-classe-objets-repensé

Est-ce que cela signifie que pour créer plusieurs propriétés statiques, je dois les regrouper dans un bloc d'objet compagnon?

Oui. Chaque propriété/méthode "statique" doit être placée dans ce compagnon.

Pour créer instantanément une instance de singleton étendue à une classe, j'écris souvent

Vous ne créez pas l'instance singleton instantanément. Il est créé lors de la première utilisation de singleton.

ce qui semble être une façon unidiomatique de le faire. Quel est le meilleur moyen?

Allez plutôt avec object Singleton { } pour définir une classe singleton. Voir: Déclarations d'objet Il n'est pas nécessaire de créer une instance de Singleton, utilisez-la simplement comme ça Singleton.doWork()

Gardez simplement à l'esprit que Kotlin propose d'autres outils pour organiser votre code. Il existe maintenant des alternatives aux fonctions statiques simples, par exemple. vous pouvez utiliser les fonctions de haut niveau à la place.

15
D3xter

Pourquoi s'appelle-t-il "compagnon"?

Une déclaration d'objet à l'intérieur d'une classe peut être marquée avec le mot clé compagnon:

class MyClass {
    companion object Factory {
        fun create(): MyClass = MyClass()
    }
}

Les membres de l'objet compagnon peuvent être appelés en utilisant simplement le nom de la classe comme qualificatif:

val instance = MyClass.create()

Si vous utilisez uniquement 'objet' sans 'compagnon', procédez comme suit:

val instance = MyClass.Factory.create()

Dans ma compréhension, «compagnon» signifie que cet objet est un compagnon de la classe extérieure.

4
Lyn

Nous pouvons dire que compagnon est identique à "Static Block" comme Java, mais dans le cas de Kotlin, il n'y a pas de concept de bloc statique, mais compagnon entre dans le cadre.

Comment définir un bloc compagnon:

class Example {
      companion object {
        fun display(){
        //place your code
     }
  }
}

Méthode d'appel du bloc compagnon, directe avec le nom de la classe

Example.Companion.display
0
Ankur Yadav