Différence entre objet et classe dans Scala

636

Je viens de passer en revue certains tutoriels Scala sur Internet et j'ai remarqué dans certains exemples qu'un objet est déclaré au début de l'exemple.

Quelle est la différence entre classet objectà Scala?

Steve
la source

Réponses:

580

tl; dr

  • class C définit une classe, tout comme en Java ou C ++.
  • object Ocrée un objet singletonO comme instance d'une classe anonyme; il peut être utilisé pour contenir des membres statiques qui ne sont pas associés à des instances d'une classe.
  • object O extends Tfait de l'objet Oune instance de trait T; vous pouvez ensuite passer On'importe où, un Test attendu.
  • s'il y en a class C, alors object Cl' 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 l' objet et la classe .

object en tant que membre statique

Le plus souvent, vous avez besoin d'un objectpour conserver les méthodes et les valeurs / variables qui seront disponibles sans avoir à instancier d'abord une instance d'une classe. Cette utilisation est étroitement liée aux staticmembres de Java.

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

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

Si vous twiceétiez membre d'une classe A, vous devez d'abord créer une instance:

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

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

Vous pouvez voir à quel point cela est redondant, car twiceil ne nécessite aucune donnée spécifique à l'instance.

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

Vous pouvez également utiliser le objectlui - même comme une instance spéciale d'une classe ou d'un trait. Lorsque vous faites cela, votre objet doit en étendre traitafin de devenir une instance d'une sous-classe de celui-ci.

Considérez le code suivant:

object A extends B with C {
  ...
}

Cette déclaration déclare d'abord une classe anonyme (inaccessible) qui étend à la fois Bet Cet instancie une seule instance de cette classe nommée A.

Cela signifie Apeut être passé aux fonctions qui attendent des objets de type Bou C, ou B with C.

Caractéristiques supplémentaires de object

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

  • def apply(...) active la syntaxe sans nom de méthode habituelle de A(...)
  • def unapply(...)permet de créer des extracteurs de correspondance de motifs personnalisés
  • s'il accompagne une classe du même nom, l'objet assume un rôle spécial lors de la résolution des paramètres implicites
ziggystar
la source
38
Il définira également la classe A et créera toutes les méthodes de l'objet A en tant que méthodes statiques sur la classe A (pour l'interfaçage avec Java). (Modulo un bug dans Scala 2.7 qui a été corrigé dans Scala 2.8)
Ken Bloom
2
@KenBloom vraiment? J'ai essayé et ne fonctionne pas: scala> Commerce res8: Commerce.type = Commerce $ @ 6eb2756 scala> classOf [Commerce] <console>: 23: erreur: introuvable: tapez Commerce classOf [Commerce] ^ scala> new Commerce < console>: 23: erreur: introuvable: tapez Commerce new Commerce ^
Hendy Irawan
3
@Hendy: Scala ne reconnaîtra pas la Commerceclasse, 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.)
Ken Bloom
3
Je pense que la réponse de ziggystar est plus précise, la classe est une classe anonyme, à moins qu'une classe correspondante nommée Commerce ne soit explicitement définie (alors l'objet Commerce sera un objet compagnon de la classe Commerce)
Hendy Irawan
3
@DavidApltauer Je parie qu'il y a suffisamment de subtilités qui ne sont pas couvertes par ma réponse. Mais cela n'a probablement pas d'importance pour la plupart des gens qui lisent ceci. Et je n'ai jamais eu de problème avec le passage d'un objet comme exemple d'un trait, ce qui ne veut pas dire qu'ils n'existent pas; mais ça devrait marcher.
ziggystar
249

A classest une définition, une description. Il définit un type en termes de méthodes et de composition d'autres types.

An objectest un singleton - une instance d'une classe qui est garantie d'être unique. Pour chaque objectélément du code, une classe anonyme est créée, qui hérite de toutes les classes que vous avez déclaré objectimplémenter. Cette classe ne peut pas être vue à partir du code source de Scala - bien que vous puissiez y accéder par la réflexion.

Il existe une relation entre objectet class. Un objet est dit être l'objet-compagnon d'une classe s'ils partagent le même nom. Lorsque cela se produit, chacun a accès à des méthodes de privatevisibilité dans l'autre. Cependant, ces méthodes ne sont pas automatiquement importées. Vous devez soit les importer explicitement, soit les préfixer avec le nom de classe / objet.

Par exemple:

class X {
  // class X can see private members of object X
  // Prefix to call
  def m(x: Int) = X.f(x)

  // Import and use
  import X._
  def n(x: Int) = f(x)

  private def o = 2
}

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

  // object X can see private members of class X
  def g(x: X) = {
    import x._
    x.o * o // fully specified and imported
   }
}
Daniel C. Sobral
la source
1
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 de les préfixer?
ithkuil
4
@ithkuil Done. Désolé pour l'exemple stupide, je ne pouvais pas penser à un bon et court.
Daniel
Et si je veux utiliser les méthodes de classe dans Object? Cela serait-il possible? Si j'ai une méthode d'une classe et que je veux l'utiliser dans Object, alors si vous essayez d'importer la classe, vous ne pourrez pas. Finalement, vous devez créer un constructeur et appeler la méthode ensuite. Ainsi, en créant un objet compagnon, vous pouvez accéder aux méthodes de Object en utilisant l'importation mais pas l'inverse. Quelqu'un peut-il valider s'il vous plaît?
piyushGoyal
@piyushGoyal Pas vrai. Supposons que l'objet possède une méthode def f(x: X) = ???, il pourrait alors appeler des méthodes privées xde la classe compagnon X.
Daniel
Ici X passé dans la fonction est une instance de classe XI devine? Si oui, alors finalement vous utilisez l'objet x pour appeler la méthode de la classe X dans le def f.
piyushGoyal
76

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

Objet sert le même (et certains supplémentaires) fins que les méthodes statiques et les champs en Java.

Thomas Jung
la source
19

Comme cela a été expliqué par beaucoup, objectdéfinit une instance singleton. La seule chose dans les réponses ici qui, je crois, est omise, c'est qu'elle objectsert à plusieurs fins.

  • Il peut s'agir de l'objet compagnon d'un class/ trait, contenant ce qui pourrait être considéré comme des méthodes statiques ou des méthodes pratiques.

  • Il peut agir un peu comme un module, contenant des définitions et des types associés / subsidiaires, etc.

  • Il peut implémenter une interface en étendant un classou un ou plusieurs traits.

  • Il peut représenter le cas d'un sealed traitqui ne contient aucune donnée. À cet égard, il est souvent considéré comme plus correct qu'un case classsans aucun paramètre. Le cas particulier d'un sealed traitavec uniquement des case objectimplémenteurs est plus ou moins la version Scala d'une énumération.

  • Il peut servir de preuve à implicitune logique motivée.

  • Il introduit un type singleton.

C'est une construction très puissante et générale. Ce qui peut être très déroutant pour les débutants de Scala, c'est que la même construction peut avoir des utilisations très différentes. Et un objectpeut servir plusieurs de ces différentes utilisations à la fois, ce qui peut être encore plus déroutant.

acjay
la source
18

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

Ken Bloom
la source
17

La différence formelle -

  1. vous ne pouvez pas fournir de paramètres de constructeur pour les objets
  2. L'objet n'est pas un type - vous ne pouvez pas créer d'instance avec un nouvel opérateur. Mais il peut avoir des champs, des méthodes, étendre une superclasse et mélanger des traits.

La différence d'utilisation:

  • Scala n'a pas de méthodes ou de champs statiques. Au lieu de cela, vous devez utiliser object. Vous pouvez l'utiliser avec ou sans classe associée. Dans le premier cas, il s'agit d'un objet compagnon. Vous devez:
    1. utiliser le même nom pour la classe et l'objet
    2. mettez-les dans le même fichier source.
  • Pour créer un programme, vous devez utiliser la méthode principale dans object, pas dans class.

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

      
        
      

irudyak
la source
"vous ne pouvez pas fournir de paramètres de constructeur pour les objets" Les objets ont la méthode apply (...), qui fonctionne un peu comme un constructeur. Cela me laisse un peu confus.
Danielle
7

Le mot-clé object crée un nouveau type singleton, qui est comme une classe qui n'a qu'une seule instance nommée. Si vous connaissez Java, déclarer un objet dans Scala est un peu comme créer une nouvelle instance d'une classe anonyme.

Scala n'a pas d'équivalent au mot-clé statique de Java et un objet est souvent utilisé dans Scala où vous pouvez utiliser une classe avec des membres statiques en Java.


la source
6

L'objet est une classe mais il a déjà (est) une instance, vous ne pouvez donc pas appeler new ObjectName. D'un autre côté, Class est juste du type et peut être une instance en appelant new ClassName().

Yonggoo Noh
la source
4

En scala, il n'y a pas de staticconcept. Scala crée donc un objet singleton pour fournir un point d'entrée pour l'exécution de votre programme. Si vous ne créez pas d'objet singleton, votre code se compilera correctement mais ne produira aucune sortie. Les méthodes déclarées à l'intérieur de Singleton Object sont accessibles globalement. Un objet singleton peut étendre des classes et des traits.

Exemple d'objet Scala Singleton

object Singleton{  
    def main(args:Array[String]){  
        SingletonObject.hello()         // No need to create object.  
    }  
}  


object SingletonObject{  
    def hello(){  
        println("Hello, This is Singleton Object")  
    }  
}  

Production:

Hello, This is Singleton Object

Dans scala, lorsque vous avez une classe portant le même nom que l'objet singleton, elle est appelée classe compagnon et l'objet singleton est appelé objet compagnon.

La classe compagnon et son objet compagnon doivent tous deux être définis dans le même fichier source.

Exemple d'objet compagnon Scala

class ComapanionClass{  
    def hello(){  
        println("Hello, this is Companion Class.")  
    }  
}  
object CompanoinObject{  
    def main(args:Array[String]){  
        new ComapanionClass().hello()  
        println("And this is Companion Object.")  
    }  
}  

Production:

Hello, this is Companion Class.
And this is Companion Object.

En scala, une classe peut contenir:

1. Membre de données

2. Méthode des membres

3. Bloc constructeur

4. Classe imbriquée

5. Super informations sur la classe, etc.

Vous devez initialiser toutes les variables d'instance de la classe. Il n'y a pas de portée par défaut. Si vous ne spécifiez pas la portée d'accès, elle est publique. Il doit y avoir un objet dans lequel la méthode principale est définie. Il fournit un point de départ pour votre programme. Ici, nous avons créé un exemple de classe.

Exemple de classe Scala

class Student{  
    var id:Int = 0;                         // All fields must be initialized  
    var name:String = null;  
}  
object MainObject{  
    def main(args:Array[String]){  
        var s = new Student()               // Creating an object  
        println(s.id+" "+s.name);  
    }  
} 

Je suis désolé, je suis trop tard mais j'espère que cela vous aidera.

Bhaskar Das
la source
2

Scala classe identique à Java Class mais scala ne vous donne aucune méthode d'entrée dans la classe, comme la méthode principale en java. La principale méthode associée au mot-clé objet. Vous pouvez considérer le mot clé object comme la création d'un objet singleton d'une classe définie implicitement.

plus d'informations consultez cette classe d' article et le mot-clé objet dans la programmation scala

FOD
la source
2

L'objet est similaire à la classe statique de Java dans une certaine mesure, la caractéristique statique signifie que la classe statique n'a pas besoin de créer un objet lors de la mise à la JVM, il peut être utilisé directement par son nom de classe et la même instance (même état de données ) est partagé partout où il est utilisé.

David
la source
1

Une classe est comme n'importe quelle autre classe dans d'autres langues. Vous définissez la classe comme n'importe quel autre langage avec une différence de syntaxe.

class Person(val name: String)
val me = new Person("My name")

Cependant, objet est une classe avec un seul objet. Cela le rend intéressant car il peut être utilisé pour créer des membres statiques d'une classe à l'aide d'un objet compagnon . Cet objet compagnon a accès aux membres privés de la définition de classe et il porte le même nom que la classe que vous définissez.

class Person(var name: String) {

  import Person._

  def hi(): String = sayHello(name)
}

object Person {
  private def sayHello(name: String): String = "Hello " + name
}

val me = new Person("My name")
me.hi()

En outre, il convient de noter que la classe d'objets est créée paresseusement, ce qui est un autre point important. Donc, ceux-ci ne sont instanciés que s'ils sont nécessaires dans notre code.

Si vous définissez la création de connexions pour JDBC, vous pouvez les créer à l'intérieur de l'objet pour éviter la duplication, comme nous le faisons en Java avec des objets singleton.

Piyush Patel
la source
0

Si vous venez de l'arrière-plan java, le concept de classe dans scala est un peu similaire à Java, mais la classe dans scala ne peut pas contenir de membres statiques.

Les objets dans scala sont de type singleton que vous appelez des méthodes à l'intérieur en utilisant le nom de l'objet, dans scala object est un mot-clé et dans java object est une instance de classe

Vivek
la source