86 votes

Kotlin : Différence entre objet et objet compagnon dans une classe

Quelle est la différence entre un objet et un objet compagnon dans une classe en kotlin ?

Ejemplo:

class MyClass {

    object Holder {
        //something
    }

    companion object {
        //something
    }
}

J'ai déjà lu que l'objet compagnon doit être utilisé si les paramètres/méthodes qu'il contient sont étroitement liés à sa classe.

Mais pourquoi y a-t-il aussi la possibilité de déclarer un objet normal dans la classe ? Parce qu'il se comporte exactement comme le compagnon, mais il doit avoir un nom.

Y a-t-il une différence dans son cycle de vie "statique" (je suis du côté de Java) ?

4 votes

object pour les singletons et companion object pour les méthodes statiques. Kotlin - Déclarations d'objets fournit une bonne explication de l'utilisation.

70voto

Mike Points 2615

Il existe deux types différents de object utilise, expression y déclaration .

Expression d'objet

Une expression objet peut être utilisée lorsqu'une classe doit être légèrement modifiée, mais qu'il n'est pas nécessaire de créer une sous-classe entièrement nouvelle pour elle. Les classes internes anonymes en sont un bon exemple.

button.setOnClickListener(object: View.OnClickListener() {
    override fun onClick(view: View) {
        // click event
    }
})

Une chose à laquelle il faut faire attention, c'est que les classes internes anonymes peuvent accéder à des variables de la portée englobante, et ces variables ne doivent pas forcément être final . Cela signifie qu'une variable utilisée à l'intérieur d'une classe interne anonyme qui n'est pas considérée comme étant final peut changer de valeur de manière inattendue avant que l'on y accède.

Déclaration d'objet

Une déclaration d'objet est similaire à une déclaration de variable et ne peut donc pas être utilisée à droite d'une instruction d'affectation. Les déclarations d'objets sont très utiles pour mettre en œuvre le modèle Singleton.

object MySingletonObject {
    fun getInstance(): MySingletonObject {
        // return single instance of object
    }
}

Et le getInstance peut alors être invoquée comme suit.

MySingletonObject.getInstance()

Objet compagnon

Un objet compagnon est un type spécifique de déclaration d'objet qui permet à un objet d'agir de manière similaire aux objets statiques dans d'autres langages (comme Java). Ajout de companion à la déclaration d'objet permet d'ajouter la fonctionnalité "static" à un objet, même si le concept de static n'existe pas en Kotlin. Voici un exemple de classe avec des méthodes d'instance et des méthodes compagnons.

class MyClass {
  companion object MyCompanionObject {
    fun actsAsStatic() {
      // do stuff
    }
  }

  fun instanceMethod() {
    // do stuff
  }
}

L'appel de la méthode d'instance ressemblerait à ceci.

var myClass = MyClass()
myClass.instanceMethod()

L'appel de la méthode de l'objet compagnon ressemblerait à ceci.

MyClass.actsAsStatic()

Voir le Documentation sur Kotlin pour plus d'informations.

2 votes

Merci Mike ! Cela devrait être la réponse.

2 votes

J'ai dû utiliser la méthode à l'intérieur de l'objet compagnon comme MyClass.MyCompanionObject.actsAsStatic() o MyClass.Companion.actsAsStatic() si l'objet compagnon n'avait pas de nom. S'agit-il d'une nouvelle modification ou ai-je fait quelque chose de mal ? Merci.

52voto

yole Points 3628

Les objets peuvent implémenter des interfaces. À l'intérieur d'une classe, définir un objet simple qui n'implémente aucune interface n'a aucun avantage dans la plupart des cas. En revanche, la définition de plusieurs objets qui implémentent diverses interfaces (par exemple Comparator ) peuvent être très utiles.

En termes de cycle de vie, il n'y a pas de différence entre un objet compagnon et un objet nommé déclaré dans une classe.

0 votes

AFAIK, il y a une certaine différence dans l'ordre d'initialisation.

0 votes

Quelle est la différence ? Je suppose que le compagnon est initialisé en premier, parce qu'il est lié à sa classe, puis l'objet est appelé ?

39 votes

L'objet compagnon est initialisé à partir du constructeur statique de la classe contenante et l'objet simple est initialisé paresseusement lors du premier accès à cet objet.

12voto

mightyWOZ Points 405

Comme Kotlin en action États

Le mot-clé objet apparaît dans Kotlin dans un certain nombre de cas, mais ils partagent tous la même idée de base : le mot-clé définit une classe et crée une une instance (en d'autres termes, un objet) de cette classe en même temps. même temps.

lorsqu'il s'agit d'un objet simple et d'un objet compagnon, la seule différence significative est que l'on peut accéder aux propriétés et aux fonctions d'un objet compagnon en utilisant directement le nom de la classe qui le contient, ce qui ressemble à l'accès aux membres statiques de java.

par exemple, si vous avez la classe suivante

class Temp{
    object Holder{
        fun foo() = 1
    }

    companion object{
        fun foo() = "Hello World"
    }
}

alors vous pouvez accéder à ces deux objets comme suit Depuis la classe contenant

foo()   // call to companion object function
Holder.foo() // call to plain object function

et de l'extérieur de la classe

Temp.foo() // call to companion object function
Temp.Holder.foo() // call to plain object function

Sous le capot, chaque déclaration d'objet crée un singleton. Dans le cas d'un objet compagnon, l'objet singleton est créé dans l'initialisateur statique de la classe qui le contient. Mais dans le cas d'objets simples, l'instance singleton est créée paresseusement lorsque la classe d'objet est accédée pour la première fois.

Vous pouvez le constater par vous-même en compilant la classe kotlin, puis en décompilant les fichiers de classe générés à l'aide d'un décompilateur java.

Quant à la raison pour laquelle il est également possible de déclarer un objet normal dans la classe, considérez la classe suivante où un objet membre est très utile.

data class Employee(val name: String) {
    object NameComparator : Comparator<Employee> {
         override fun compare(p1: Employee, p2: Employee): Int =
             p1.name.compareTo(p2.name)
    }
}

maintenant nous pouvons trier une liste d'employés comme

list.sortedWith(Employee.NameComparator))

9voto

Supriya Points 939

Un objet, ou une déclaration d'objet, est initialisé paresseusement, lors du premier accès.

Un objet compagnon est initialisé lorsque la classe correspondante est chargée. Il apporte l'essence "statique", bien que Kotlin ne supporte pas intrinsèquement les membres statiques.

5voto

Swati Singh Points 61

A Objet de compagnie est initialisée lorsque la classe est chargée (généralement la première fois qu'elle est référencée par un autre code en cours d'exécution) alors que l'option Objet sont initialisées paresseusement, lors du premier accès.

Veuillez vous référer à https://kotlinlang.org/docs/reference/object-declarations.html La section inférieure de l'en bas de l'écran définit clairement la différence entre ces deux différences.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X