web-dev-qa-db-fra.com

Quelle est la raison d'être des objets compagnons dans Scala?

Existe-t-il un cas où un objet compagnon (singleton) pour une classe est nécessaire? Pourquoi voudrais-je créer une classe, disons Foo et aussi créer un objet compagnon pour celle-ci?

95
Rahul

L'objet compagnon fournit fondamentalement un endroit où l'on peut mettre des méthodes "statiques". En outre, un objet compagnon ou un module compagnon dispose d'un accès complet aux membres de la classe, y compris les membres privés.

Les objets compagnons sont parfaits pour encapsuler des choses telles que les méthodes d'usine. Au lieu d'avoir, par exemple, Foo et FooFactory partout, vous pouvez avoir une classe avec un objet compagnon assumer les responsabilités de l'usine.

72
Saem

Les objets Compagnon sont utiles pour stocker l'état et les méthodes communes à toutes les instances d'une classe mais ils n'utilisent pas de méthodes ni de champs static. Ils utilisent des méthodes virtuelles régulières qui peuvent être remplacées par héritage. Scala n'a vraiment rien de statique. Ceci peut être utilisé de nombreuses manières, mais voici un exemple simple.

abstract class AnimalCounter
{
    var animals = 0

    def name: String

    def count()
    {
        animals += 1
        println("%d %ss created so far".format(animals, name))
    }
}

abstract class Animal
{
    def companion: AnimalCounter
    companion.count()
}

object Dog extends AnimalCounter
{
    val name = "dog"
}

class Dog extends Animal
{
    def companion = Dog
}

object Cat extends AnimalCounter
{
    val name = "cat"
}

class Cat extends Animal
{
    def companion = Cat
}

Qui produit cette sortie:

scala> new Dog
1 dogs created so far

scala> new Cat
1 cats created so far

scala> new Dog
2 dogs created so far

scala> new Cat
2 cats created so far
59
Craig P. Motlin

... et c'est un bon endroit pour stocker des méthodes d'usine statiques (pas celle DP) pour les cours accompagnés. Si vous nommez ces méthodes de fabrique surchargées applicables (/ ... /), vous pourrez créer/initialiser votre classe 

  1. sans 'nouveau' (pas vraiment important)

  2. avec différents jeux de paramètres possibles (à comparer avec ce que Bloch écrit dans Effective Java à propos du constructeur télescopique)

  3. avec la possibilité de décider quelle classe dérivée vous voulez créer au lieu de la classe abstraite (accompagnée)

Exemple de code:

abstract class AbstractClass;
class RealThing(s: String) extends AbstractClass;
class AlternativeThing(i: Int) extends AbstractClass;
object AbstractClass {
  def apply(s: String) = {
    new RealThing(s)
  }
  def apply(i: Int) = {
    new AlternativeThing(i)
  }
}

// somewhere else you can
val vs = AbstractClass("asdf")  // gives you the RealThing wrapped over string
val vi = AbstractClass(123)  // gives you AlternativeThing wrapped over int

Je n'appellerais pas la classe d'objet/base AbstractXxxxx parce que ça n'a pas l'air mal: comme de créer quelque chose d'abstrait. Donnez à ces noms un sens réel… Pensez à utiliser les classes immuable, méthode less, case et scellez la classe de base abstraite. 

30
Szymon Jachim

En plus de ce que Saem a dit dans his reply , le compilateur Scala recherche également des conversions implicites de types dans les objets compagnons correspondants (de la source ou de la cible), de sorte que les conversions ne doivent être importés.

À propos de la raison des objets singleton en général Programmation en Scala dit:

Comme indiqué au chapitre 1, Scala est plus orienté objet que Java: les classes de Scala ne peuvent pas avoir de membres statiques. À la place, Scala contient des objets singleton (p. 65).

19
Fabian Steeg

Je vois toujours les objets compagnons comme un pont pour écrire du code fonctionnel et orienté objet dans Scala. Plusieurs fois, nous avons simplement besoin de fonctions pures qui prennent certaines entrées et fournissent un résultat de traitement. Le fait de placer ces fonctions pertinentes dans l'objet compagnon facilite la recherche et l'utilisation, aussi bien pour moi-même que pour celui qui construit au-dessus de mon code. 

De plus, c’est une fonctionnalité fournie par le langage qui permet d’écrire le motif singleton sans rien faire. Ceci est particulièrement utile lorsque vous avez besoin d'un singleton pour encapsuler un délégateur pendant la vie de la machine virtuelle Java. Par exemple, l'écriture d'une bibliothèque client HTTP simple dans Scala dans laquelle vous pouvez encapsuler un délégateur sous-jacent implémenté en Java et laisser les utilisateurs de votre API vivre dans un monde pur.

3
Gaurav Abbi

Au début, il fournit une séparation claire des méthodes méthodes statiques et non statiques. Il fournit également un moyen simple de créer une classe singleton.

Il peut également hériter des méthodes d'autres classes et/ou traits, ce qui n'est pas possible avec les méthodes statiques Java. Il peut également être transmis en tant que paramètre.

0
vipin

Si vous définissez la classe et l'objet dans le même fichier avec le même nom, ils sont appelés classe et objet compagnon. Scala n’a pas de mot de passe statique en tant que mot-clé Java. Vous pouvez le remplacer par une classe et un objet associés dans Scala.

Pour plus d'informations, consultez l'article mot clé class and object dans la programmation scala

0
FOD