Pourquoi utilisons-nous" companion object " comme une sorte de remplacement pour les champs statiques Java à Kotlin?
Quel est le sens de "compagnon de l'objet"? Jusqu'à présent, je l'ai utilisé pour remplacer Java static
quand j'en ai besoin.
je suis confondu avec:
- pourquoi s'appelle-t-on"compagnon"?
- signifie-t-il que pour créer plusieurs propriétés statiques , je dois les regrouper à l'intérieur du bloc
companion object
? - pour créer instantanément une instance singleton qui est scoped à une classe, j'écris souvent
:
companion object {
val singleton by lazy { ... }
}
ce qui semble être une façon unidiomatique de le faire. Quelle est la meilleure façon de faire?
3 réponses
-
Quel est le sens de "compagnon de l'objet"? Pourquoi ça s'appelle "compagnon"?
tout D'abord, Kotlin n'utilise pas le concept Java des membres
static
parce que Kotlin a son propre concept deobject
s pour décrire les propriétés et les fonctions liées à l'état singleton, et Javastatic
partie d'une classe peut être exprimée élégamment en termes de singleton: c'est un objet unique qui peut être appelé par le nom de la classe. D'où le nom: c'est un objet qui vient avec une classe.son nom était
class object
etdefault object
, mais ensuite il a été renommé encompanion object
ce qui est plus clair et est également compatible avec Scala companion objects .en plus de nommer, il est plus puissant que Java
static
membres: il peut étendre les classes et les interfaces, et vous pouvez le référencer et le transmettre comme les autres objets. -
signifie-t-il que pour créer plusieurs propriétés statiques, je dois les regrouper à l'intérieur du bloc
companion object
?Oui, c'est la façon idiomatique. Ou vous pouvez même les regrouper dans des objets non-companions par leur sens:
class MyClass { object IO { fun makeSomethingWithIO() { /* ... */ } } object Factory { fun createSomething() { /* ... */ } } }
-
pour créer instantanément une instance singleton qui est scopée à une classe, j'écris souvent
/*...*/
qui semble être une façon unidiomatique de le faire. Quelle est la meilleure façon de faire?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 dès le premier appel.
si vous n'avez pas besoin d'être connecté à une classe, utilisez simplement object déclaration:
object Foo { val something by lazy { ... } }
vous pouvez également supprimer
lazy { ... }
délégation pour rendre la propriété initialiser sur l'usage de première classe, tout comme Java static initialisersvous pourriez également trouver des moyens utiles de initialisant l'état singleton .
pourquoi s'appelle-t-on "compagnon"?
Cet objet est un compagnon des instances. IIRC il y a eu une longue discussion ici: à venir-changement-classe-objets-repensée
signifie-t-il que pour créer des propriétés statiques multiples, je dois les regrouper à l'intérieur du bloc d'objets compagnon?
Oui. Chaque propriété/méthode" statique " doit être placé à l'intérieur de ce compagnon.
pour créer instantanément une instance singleton qui est scoped à une classe, j'écris souvent
vous ne créez pas l'instance singleton instantanément. Il est créé lors de l'accès singleton
pour la première fois.
ce qui semble être une façon unidiomatique de le faire. Quelle est la meilleure façon de faire?
plutôt aller avec object Singleton { }
pour définir un singleton de classe. Voir: Déclarations D'Objet
Vous n'avez pas à créer une instance de Singleton
, il suffit de l'utiliser comme cela Singleton.doWork()
il suffit de garder à l'esprit que Kotlin offre d'autres choses pour organiser votre code. Il existe maintenant des alternatives aux fonctions statiques simples, par exemple vous pouvez utiliser des fonctions de haut niveau à la place.
pourquoi s'appelle-t-on "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 classe comme qualificatif:
val instance = MyClass.create()
si vous utilisez seulement "objet" sans "compagnon", vous devez faire comme ceci:
val instance = MyClass.Factory.create()
d'après ce que j'ai compris, "compagnon" signifie que cet objet est compagnon avec le outter classe.