Un objet est une classe qui a exactement une instance. Il est créé de façon paresseuse au moment où il est référencé, comme une valeur paresseuse lazy val
.
En tant que valeur de premier niveau, un objet est un singleton.
En tant que membre d’une classe englobante ou en tant que valeur locale, il se comporte exactement comme une lazy val
.
Définir un objet singleton
Un objet est une valeur. La définition d’un objet ressemble a une classe, mais utilise le mot clef object
:
object Box
Voici un exemple d’un objet avec une méthode :
package logging
object Logger {
def info(message: String): Unit = println(s"INFO: $message")
}
La méthode info
peut être importée depuis n’importe où dans le programme. Créer des méthodes utilitaires, comme celle-ci, est un cas d’usage commun pour les objets singleton.
Regardons comment utiliser info
dans un autre package :
import logging.Logger.info
class Project(name: String, daysToComplete: Int)
class Test {
val project1 = new Project("TPS Reports", 1)
val project2 = new Project("Website redesign", 5)
info("Created projects") // Prints "INFO: Created projects"
}
La méthode info
est visible grâce à l’import, import logging.Logger.info
. Les imports ont besoin d’un chemin d’accès stable aux ressources, et un objet est un chemin stable.
Note : Si un objet
est encapsulé dans une autre classe ou un autre objet, alors l’objet est dépendant du chemin d’accès, comme les autres membres. Cela veut dire, par exemple, que si on prend 2 types de boissons, class Milk
et class OrangeJuice
, un membre de classe object NutritionInfo
est dépendant de son instance d’encapsulation. milk.NutritionInfo
est complètement différent de oj.NutritionInfo
.
Les objets compagnons
Un objet avec le même nom qu’une classe est appelé un objet compagnon. Inversement, la classe se nomme la classe compagnon de l’objet. Une classe ou un objet compagnon peut accéder aux membres privés de son compagnon. L’objet compagnon est utile pour les méthodes et les valeurs qui ne sont pas spécifiques aux instances de la classe compagnon.
import scala.math._
case class Circle(radius: Double) {
import Circle._
def area: Double = calculateArea(radius)
}
object Circle {
private def calculateArea(radius: Double): Double = Pi * pow(radius, 2.0)
}
val circle1 = Circle(5.0)
circle1.area
La classe class Circle
a un membre area
qui est spécifique à chaque instance, et un singleton object Circle
qui a une méthode calculateArea
qui est disponible pour chaque instance.
L’objet compagnon peut aussi contenir des méthodes de fabrique (factory) :
class Email(val username: String, val domainName: String)
object Email {
def fromString(emailString: String): Option[Email] = {
emailString.split('@') match {
case Array(a, b) => Some(new Email(a, b))
case _ => None
}
}
}
val scalaCenterEmail = Email.fromString("scala.center@epfl.ch")
scalaCenterEmail match {
case Some(email) => println(
s"""Registered an email
|Username: ${email.username}
|Domain name: ${email.domainName}
""".stripMargin)
case None => println("Error: could not parse email")
}
L’objet object Email
contient une méthode de fabrique fromString
qui créé une instance de Email
depuis une chaîne de caractères. L’instance est retournée en tant que Option[Email]
pour gérer le cas des erreurs de syntaxe.
Note : Si une classe ou un objet a un compagnon, tous deux doivent être définis dans le même fichier. Pour définir des compagnons dans le REPL, tous deux doivent être définis sur la même ligne ou définis en mode :paste
.
Notes pour les programmeurs Java
Les membres static
en Java sont modélisés comme des membres ordinaires d’un objet compagnon en Scala.
Lorsqu’on utilise un objet compagnon depuis du code Java, ses membres sont définis dans la classe compagnon avec le modificateur static
. Cela s’appelle le static forwarding. Cela se produit même si vous n’avez pas défini de classe compagnon vous-même.
Plus d’informations
- Apprenez-en plus sur les objets compagnons dans le Scala Book
Traduit par Antoine Pointeau.
Contributors to this page:
Contents
- Introduction
- Basics
- Unified Types
- Classes
- Default Parameter Values
- Named Arguments
- Traits
- Tuples
- Class Composition with Mixins
- Higher-order Functions
- Nested Methods
- Multiple Parameter Lists (Currying)
- Case Classes
- Pattern Matching
- Singleton Objects
- Regular Expression Patterns
- Extractor Objects
- For Comprehensions
- Generic Classes
- Variance
- Upper Type Bounds
- Lower Type Bounds
- Inner Classes
- Abstract Type Members
- Compound Types
- Self-types
- Implicit Parameters
- Implicit Conversions
- Polymorphic Methods
- Type Inference
- Operators
- By-name Parameters
- Annotations
- Packages and Imports
- Package Objects