Les Classes

Voir la vidéo
Description Sommaire

Tout au long des chapitres précédent nous avons utiliser des objets comme des entiers, des tableaux ou des chaines de caractères. Lorsque notre application va grandir nous allons vouloir représenter des concepts plus élaborés que ceux proposés par Ruby. On pourra alors utiliser des classes pour définir ces nouveaux objets.

Les instances

class Eleve

end

jean = Eleve.new
marc = Eleve.new

Pour le moment notre class ne fait rien mais il est important de faire un points sur la terminologie. Dans l'exemple précédent jean et marc sont des instances de la classe Eleve. Cela veut dire qu'ils sont construit sur le même modèle mais qu'ils ne sont pas réellement identique. Si on rapproche ça avec ce que nous avont déjà vu les chiffre 1 et 2 sont des instances de la class Fixnum.

Les classes que l'on définit peuvent contenir des méthodes

class Eleve
    def marcher
       puts "Je marche"
    end
end

jean = Eleve.new
jean.marcher

Il est possible de définir une méthode spéciale initialize, cette méthode est automatiquement appellée à la construction d'une nouvelle instance, lors de l'utilisation de new, il est aussi possible de lui assigner des arguments.

class Eleve
    def initialize(nom)
       @nom = nom
    end
end

jean = Eleve.new("Jean")

Dans l'exemple précédent, on remarque qu'une varialbe possède un @ devant son nom. Ce @ permet de désigner une variable d'instance. Cela veut dire que chaque instance de la classe Eleve aura une copie unique de la variable @nom

class Eleve
    def initialize(nom)
       @nom = nom
    end

    def direNom
        puts "Je suis #{@nom}"
    end
end

Eleve.new("Jean").direNom # Je suis Jean
Eleve.new("Marc").direNom # Je suis Marc

Ici la valeur de @nom dépend de l'instance. Jean et Marc possède chacun une valeur différente pour cette variable.
Il est possible de rendre une variable d'instance facilement accessible depuis une instance en utilisant un système d'accesseurs / mutateurs (getters/setters en anglais)

class Eleve

    def taille
        @taille
    end

    def taille=(valeur)
        @taille = valeur
    end

end

jean = Eleve.new
# On peut maintenant modifier / récupérer taille facilement
jean.taille = 150
puts jean.taille # 150

Il existe un racourci pour définir ces accesseurs / mutateur pour gagner du temps et éviter de devoir déclarer des tonnes de méthodes si nous avons beaucoup de variables d'instances à rendre accessible.

class Eleve
    attr_accessor :taille, :age, :nom
end

Il existe plusieurs variantes :

  • attr_accessor, crée un getter et un setter pour chaque variable
  • attr_reader, crée un getter pour chaque variable
  • attr_writer, crée un setter pour chaque variable

Public / Privée

Dans des classes complexes nous allons parfois séparer certaines de nos méthodes afin de garder un code propre et simple. Certaines méthode n'auront pas lieu de se retrouver disponible sur les instances. On pourra alors créer des méthodes privées

class Eleve

    attr_accessor :notes

    def moyenne
        sommeNotes / @notes.length
    end

    private

    def sommeNotes
        @notes.inject(:+)
    end

end

jean = Eleve.new
jean.notes = [10, 16]
puts jean.moyenne # 13

Dans ce cas-là, la méthode permettant de faire la somme des notes n'a pas d'interêt à être accessible depuis l'instance, on la rend donc privée. Si on essaie de l'appeller depuis l'instance on obtiendra une erreur.

jean.sommeNotes
# NoMethodError: private method `sommeNotes' called

Rendre des méthodes privées n'apportent rien en terme fonctionnel mais permet de rendre la lecture d'une classe plus facile. Car on saura en un clin d'oeil les méthodes que l'on peut uiliser sur les instances. Cela permet de garder un code propre et une API simple.

Les méthodes de classes

Les classes en elle même peuvent aussi contenir des méthodes, ces méthodes sont appellées méthode de classes

class Eleve

    def self.moyenne
        10
    end

end

puts Eleve.moyenne # 10

Contrairement aux méthodes d'instance vues précédemment, ces méthodes sont appellées directement sur la classe (il n'est donc pas nécessaire de créer une instance pour les appeller). De la même manière il existe aussi des variables de classe. Ces variables sont symbolisées par `@@``

class Eleve

    @@moyenne = 10

    def self.afficherMoyenne
        puts @@moyenne
    end

    # une méthode de classe peut être appellé depuis la classe
    # Là c'est inutle mais il faut savoir que l'on peut le faire
    afficherMoyenne  # 10

end

Eleve.showMoyenne # 10

Cela nous permet maintenant d'élucider le mystère de attr_accessor vu précédemment. attr_accessor est en fait une méthode de classe qui, lorsqu'elle est appellée, a pour effet de créer les accesseur et mutateurs. C'est ce qu'on appelle du MétaProgramming, le code est capable de se modifier lui même.

Publié
Technologies utilisées
Auteur :
Grafikart
Partager