689 votes

Différence entre objet et classe en Scala

Je suis en train de consulter quelques tutoriels sur Scala sur Internet et j'ai remarqué que dans certains exemples, un objet est déclaré au début de l'exemple.

Quelle est la différence entre class et object en Scala?

634voto

ziggystar Points 9538

Tl;dr

  • class C définit une classe, tout comme en Java ou en C++.
  • object O crée un singleton objet O en tant qu'instance d'une classe anonyme; il peut être utilisé pour stocker des membres statiques qui ne sont pas associés à des instances d'une classe.
  • object O extends T fait de l'objet O une instance du trait T; vous pouvez alors passer O partout où un T est attendu.
  • si il y a une class C, alors object C est l' objet compagnon de la classe C; notez que l'objet compagnon n'est pas automatiquement une instance de C.

Voir également la documentation Scala pour object et class.

object en tant qu'hôte de membres statiques

La plupart du temps, vous avez besoin d'un object pour contenir des méthodes et des valeurs/variables qui doivent être disponibles sans avoir à instancier d'abord une instance d'une classe. Cet usage est étroitement lié aux membres static en Java.

object A {
  def deuxFois(i: Int): Int = 2 * i
}

Vous pouvez ensuite appeler la méthode ci-dessus en utilisant A.deuxFois(2).

Si deuxFois était un membre d'une classe A, alors vous auriez besoin de créer une instance d'abord :

class A() {
  def deuxFois(i: Int): Int = 2 * i
}

val a = new A()
a.deuxFois(2)

Vous pouvez voir à quel point c'est redondant, car deuxFois ne nécessite pas de données spécifiques à une instance.

object en tant qu'instance nommée spéciale

Vous pouvez également utiliser l' object lui-même en tant qu'instance spéciale d'une classe ou d'un trait. Lorsque vous faites cela, votre objet doit étendre un certain trait pour devenir une instance d'une sous-classe de celui-ci.

Considérez le code suivant:

object A extends B with C {
  ...
}

Cette déclaration crée d'abord une classe anonyme (inaccessible) qui étend à la fois B et C, et instancie une seule instance de cette classe nommée A.

Cela signifie que A peut être passé à des fonctions qui attendent des objets de type B ou C, ou B with C.

Fonctionnalités supplémentaires de object

Il existe également des fonctionnalités spéciales des objets en Scala. Je recommande de lire la documentation officielle.

  • def apply(...) permet la syntaxe habituelle sans nom de méthode de A(...)
  • def unapply(...) permet de créer des extracteurs de correspondance de motifs personnalisés
  • si accompagnant une classe du même nom, l'objet assume un rôle spécial lors de la résolution des paramètres implicites

38 votes

Il définira également la classe A et créera toutes les méthodes de l'objet A en tant que méthodes statiques de la classe A (pour l'interaction avec Java). (Sauf un bug dans Scala 2.7 qui a été corrigé dans Scala 2.8)

2 votes

@KenBloom vraiment ? J'ai essayé et ça ne marche pas : scala> Commerce res8: Commerce.type = Commerce$@6eb2756 scala> classOf[Commerce] :23: error: not found: type Commerce classOf[Commerce] ^ scala> new Commerce :23: error: not found: type Commerce new Commerce ^

3 votes

@Hendy: Scala ne reconnaîtra pas la classe Commerce, mais la JVM et le langage Java le feront. (C'est ainsi que vous pouvez faire object Foo{ def main(args:Seq[String]) } et vous attendre à ce que le programme s'exécute.)

254voto

Daniel C. Sobral Points 159554

Une class est une définition, une description. Elle définit un type en termes de méthodes et de composition d'autres types.

Un object est un singleton - une instance d'une classe qui est garantie d'être unique. Pour chaque object dans le code, une classe anonyme est créée, qui hérite des classes que vous avez déclarées object pour implémenter. Cette classe ne peut pas être vue à partir du code source Scala - bien que vous pouvez y accéder par réflexion.

Il y a une relation entre object et class. Un object est dit être le objet-compagnon d'une classe s'ils partagent le même nom. Lorsque cela se produit, chacun a accès aux méthodes de visibilité private dans l'autre. Ces méthodes ne sont pas automatiquement importées, cependant. Vous devez soit les importer explicitement, soit les préfixer avec le nom de la classe/objet.

Par exemple:

class X {
  // La classe X peut voir les membres privés de l'objet X
  // Préfixez pour appeler
  def m(x: Int) = X.f(x)

  // Importez et utilisez
  import X._
  def n(x: Int) = f(x)

  private def o = 2
}

object X {
  private def f(x: Int) = x * x

  // L'objet X peut voir les membres privés de la classe X
  def g(x: X) = {
    import x._
    x.o * o // entièrement spécifié et importé
   }
}

1 votes

Désolé de vous déranger, mais pourriez-vous peut-être indiquer un exemple sur la façon d'importer des méthodes dans l'objet compagnon ou comment les préfixer?

4 votes

@ithkuil Terminé. Désolé pour l'exemple ridicule, je n'arrivais pas à trouver un bon et court.

0 votes

Que se passe-t-il si je veux utiliser les méthodes de classe dans un objet ? Serait-ce possible ? Si j'ai une méthode d'une classe et que je veux l'utiliser dans un objet, alors si vous essayez d'importer la classe, vous ne pourrez pas. Finalement, vous devez créer un constructeur et appeler la méthode. Ainsi, en créant un objet compagnon, vous pouvez accéder aux méthodes de l'objet en important mais pas vice versa. Est-ce que quelqu'un pourrait valider ?

76voto

Thomas Jung Points 17692

Un objet a exactement une instance (vous ne pouvez pas appeler new MyObject). Vous pouvez avoir plusieurs instances d'une classe.

L'objet sert aux mêmes (et à certains autres) buts que les méthodes et champs statiques en Java.

20voto

Ken Bloom Points 27197

Définir un objet en Scala revient à définir une classe en Java qui n'a que des méthodes statiques. Cependant, en Scala, un objet peut étendre une autre superclasse, implémenter des interfaces et être passé comme s'il s'agissait d'une instance d'une classe. (Donc c'est comme les méthodes statiques d'une classe mais en mieux).

17voto

irudyak Points 39

La différence formelle -

  1. vous ne pouvez pas fournir de paramètres de constructeur pour les Objets
  2. Object n'est pas un type - vous ne pouvez pas créer une instance avec l'opérateur new. Mais il peut avoir des champs, des méthodes, étendre une superclasse et incorporer des traits.

La différence d'utilisation:

  • Scala n'a pas de méthodes ou de champs statiques. Au lieu de cela, vous devriez utiliser object. Vous pouvez l'utiliser avec ou sans classe associée. Dans le premier cas, c'est appelé un objet compagnon. Vous devez :

    1. utiliser le même nom pour la classe et l'objet
    2. les placer dans le même fichier source.
  • Pour créer un programme, vous devriez utiliser la méthode main dans object, pas dans class.

    object Hello {
      def main(args: Array[String]) {
        println("Hello, World!")
      }
    }
  • Vous pouvez également l'utiliser comme un objet singleton en java.

0 votes

"vous ne pouvez pas fournir des paramètres de constructeur pour les Objets" Les Objets ont la méthode apply(...), qui fonctionne de manière similaire à un constructeur. Cela me laisse un peu perplexe.

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