117 votes

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, dire Foo et créer un objet compagnon pour celle-ci?

87voto

Saem Points 2415

L'objet compagnon fournit fondamentalement un endroit où l'on peut mettre des méthodes «statiques». De plus, un objet compagnon, ou module compagnon, a un accès complet aux membres de la classe, y compris les membres privés.

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

65voto

Craig P. Motlin Points 11814

Les objets compagnon sont utiles pour stocker l'état et les méthodes communes à toutes les instances d'une classe, mais ils n'utilisent ni méthodes ni champs statiques . 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
 

31voto

Szymon Jachim Points 456

...et c'est un bon endroit pour stocker statique usine méthodes (pas que DP) pour accompagner les classes. Si vous le nom de ces surchargé usine méthodes s'appliquent(/.../), vous serez en mesure de créer/initialisation de vous classe

  1. sans les "nouveaux" (pas vraiment important)

  2. avec différents jeux de paramètres (comparer à ce que Bloch a écrit dans Efficace Java sur télescopique constructeur)

  3. avec la capacité de décider dérivé de classe que vous souhaitez créer à la place de l'abstrait (accompagnés) un

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 ne dirais pas l'objet/classe de base AbstractXxxxx parce qu'il ne semble pas mauvais: comme la création de quelque chose d'abstrait. Donner ces noms un sens réel. Pensez à utiliser immuable, méthode moins, des classes de cas et de sceller la classe de base abstraite.

19voto

Fabian Steeg Points 24261

En plus des choses Saem a déclaré dans sa réponse, le compilateur Scala cherche aussi les conversions implicites de types dans le compagnon des objets (de la source ou la cible), de sorte que les conversions n'ont pas besoin d'être importés.

Sur la raison de singleton objets en général, la Programmation Scala dit:

Comme mentionné dans le Chapitre 1, une forme de Scala est plus orientées objet de Java est que les classes de Scala ne peut pas avoir des membres statiques. Au lieu de cela, Scala a objets singleton (p. 65).

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