Les classes sont un concept central en programmation orientée objet. En Crystal, tout est un objet, chaque objet possède un type et peut répondre à certaines méthodes. Les classes sont des plans qui servent à créer des objets : elles fournissent des valeurs initiales pour l'état, comme les variables, et des implémentations de comportement, comme les méthodes. Les objets sont des instances de classe qui contiennent toutes les variables d'instance et les états.
Une classe se définit à l'aide du mot-clé class, suivi du nom de la classe écrit en UpperCamelCase.
class Account
end
Pour créer une instance d'une classe, appelle le nom de la classe à l'aide de la méthode new.
class Account
end
account = Account.new
Dans l'exemple ci-dessus, la variable account est une instance de la classe Account.
Lors de la création d'une instance, une méthode spéciale appelée initialize joue le rôle de constructeur.
Elle est appelée lorsqu'une instance est créée.
Le constructeur permet de définir l'état initial de l'instance.
La méthode initialize peut prendre des arguments, qui sont passés lors de la création d'une instance.
class Account
def initialize(number)
5 + number # => 9
end
end
Account.new(4)
La méthode initialize ne peut pas renvoyer de valeur manuellement ; à la place, c'est new qui renvoie l'instance qui vient d'être créée.
class Account
def initialize(number)
5 + number
end
end
Account.new(4)
# => #<Account:0x7f5dc33dcea0>
Une méthode d'instance est une méthode disponible pour une instance d'une classe, et qui peut être appelée sur cette instance.
Les méthodes d'instance se définissent à l'aide du mot-clé def, suivi du nom de la méthode.
Elles sont définies à l'intérieur de la définition de la classe.
class Account
def balance
100
end
end
account = Account.new
account.balance # => 100
Les variables d'instance sont des variables disponibles dans toutes les méthodes de l'instance.
Pour accéder à une variable d'instance, tu dois définir une méthode d'instance.
Elles peuvent être initialisées dans la méthode initialize.
Elles se définissent à l'aide du préfixe @.
class Account
def initialize
@balance = 100
end
def balance
@balance
end
end
account = Account.new
account.balance
# => 100
Les variables d'instance peuvent aussi être définies directement dans la définition de la classe.
class Account
@age = 0
end
Les variables d'instance peuvent être initialisées avec un argument passé à la méthode initialize.
Comme Crystal ne peut pas déduire le type de l'argument utilisé lors de l'initialisation, il faut le préciser.
Si tu veux en savoir plus à ce sujet, tu peux lire : l'inférence de type.
Pour préciser le type de la variable, tu peux utiliser le symbole :, suivi du type.
Par exemple, si tu veux créer une variable d'instance appelée balance de type Int32, tu peux faire comme ceci : @balance : Int32.
Ou bien, si tu veux créer une variable d'instance appelée raining de type Bool, tu peux faire comme ceci : @raining : Bool.
Il y a plusieurs façons de faire : soit déclarer l'argument avec son type dans la méthode initialize, puis affecter l'argument à la variable d'instance, comme dans l'exemple suivant :
class Account
def initialize(balance : Int32)
@balance = balance
end
def balance
@balance
end
end
account = Account.new(1)
account_2 = Account.new(5)
account.balance
# => 1
account_2.balance
# => 5
Une autre façon consiste à déclarer le type de la variable d'instance dans la définition de la classe, sous la forme @<variable> : <Type>, comme dans l'exemple suivant :
class Weather
@raining : Bool
def initialize(raining)
@raining = raining
end
def raining
@raining
end
end
weather = Weather.new(true)
weather.raining
# => true
Les méthodes peuvent modifier les variables d'instance. Ces méthodes peuvent être appelées sur l'instance de la classe. Lorsqu'une méthode modifie une variable d'instance, ce changement n'est visible que dans l'instance de la classe sur laquelle tu l'as appelée.
class Account
def initialize(balance : Int32)
@balance = balance
end
def withdraw(amount)
@balance -= amount
end
def balance
@balance
end
end
account = Account.new(10)
account_2 = Account.new(10)
account.balance
# => 10
account_2.balance
# => 10
account.withdraw(5)
account.balance
# => 5
account_2.balance
# => 10
Les méthodes de classe sont des méthodes définies pour une classe, mais pas pour ses instances.
Elles offrent un moyen de créer des méthodes qui ne dépendent pas de l'état de l'instance.
Elles se définissent à l'aide du mot-clé def, suivi de self.<method name>.
self est une référence à l'espace de noms depuis lequel self est appelé.
Ici, il désigne la classe Account.
Cela reviendrait au même que d'écrire Account., mais self. est la façon privilégiée.
class Account
def self.balance
100
end
end
Account.balance
# => 100
Ton ami Johannes adore fabriquer son propre matériel en DIY (do it yourself). Johannes vient de construire un extracteur de jus et en est très enthousiaste. L'objectif de Johannes est de pouvoir préparer du jus frais chaque matin.
L'extracteur de jus de Johannes a de nombreuses fonctionnalités sophistiquées. Comme un système de mesure intégré, qui peut t'indiquer la quantité de jus dans le verre. Il a aussi un minuteur, qui t'indique depuis combien de temps la machine tourne.
Johannes n'est pas très doué en programmation, mais il veut écrire un programme pour contrôler la machine. C'est pourquoi il t'a demandé de l'aider.
La machine possède un voyant de débogage, c'est un mécanisme simple : si la machine est alimentée, le voyant de débogage est allumé. Le programme ne s'exécute que si le voyant de débogage est allumé.
Cette méthode doit être une méthode de classe appelée JuiceMaker.
Définis la méthode de classe JuiceMaker.debug_light_on? qui renvoie true.
JuiceMaker.debug_light_on?
#=> true
Quand la machine est allumée, elle doit créer une instance d'une classe appelée JuiceMaker.
La machine est censée avoir un état initialisé.
L'état initialisé doit contenir les informations suivantes :
false quand la machine est allumée.Définis l'état initialisé, qui prend en paramètre la quantité de jus dans le verre, et construis cet état initialisé.
L'état initialisé doit comporter une variable d'instance @running qui vaut false, et une variable d'instance @fluid qui se base sur un argument fourni lors de l'initialisation de la classe.
JuiceMaker.new(5)
#=> #<JuiceMaker:0x10f0b8 @running=false, @fluid=5>
La machine peut être allumée et éteinte.
Tu dois définir une méthode pour allumer la machine.
Quand la machine est allumée, l'état de marche doit être défini à true.
Définis la méthode JuiceMaker#start qui allume la machine.
juice_maker = JuiceMaker.new(5)
juice_maker.start
juice_maker
#=> #<JuiceMaker:0x10f0b8 @running=true, @fluid=5>
La machine doit pouvoir t'indiquer son état.
Elle doit renvoyer true si la machine est en marche, et false si la machine n'est pas en marche.
Définis la méthode JuiceMaker#running? qui renvoie l'état de la machine.
juice_maker = JuiceMaker.new(5)
juice_maker.start
juice_maker.running?
#=> true
La machine peut ajouter du jus dans le verre. La machine peut déterminer la quantité de jus ajoutée au verre. La machine a besoin d'aide pour savoir quelle quantité de jus se trouve dans le verre une fois le jus ajouté.
Définis la méthode JuiceMaker#add_fluid, qui prend en paramètre la quantité de jus ajoutée et met à jour la quantité de jus dans le verre.
juice_maker = JuiceMaker.new(5)
juice_maker.add_fluid(5)
juice_maker
#=> #<JuiceMaker:0x10f0b8 @running=false, @fluid=10>
La machine peut être allumée et éteinte.
Tu dois définir une méthode pour éteindre la machine
Cette méthode ne sera appelée que lorsque la machine est en marche.
Quand la machine est éteinte, l'état de marche doit être défini à false.
La machine a aussi besoin d'aide pour déterminer la quantité de jus qui reste dans le verre après son extinction.
La machine consomme cinq unités de jus par minute.
Définis la méthode JuiceMaker#stop qui prend en paramètre le nombre de minutes pendant lesquelles la machine a tourné et qui renvoie la quantité de jus présente dans le verre une fois la machine éteinte.
juice_maker = JuiceMaker.new(5)
juice_maker.start
juice_maker
#=> <JuiceMaker:0x10f0b8 @running=true, @fluid=5>
juice_maker.stop(1)
#=> #<JuiceMaker:0x10f0b8 @running=false, @fluid=0>
Inscris-toi sur Exercism pour apprendre et maîtriser Crystal avec 26 concepts142 exercices, et un vrai mentorat humain, le tout gratuitement.