< Ruby
fin de la boite de navigation du chapitre

À partir de maintenant, nous allons distinguer deux usages de méthodes :

  1. Ce que nous avons vu dans la première partie, à savoir déclarer une méthode en dehors de toute classe. On pourra l’utiliser partout dans le fichier. Elle ne sera pas liée à un type d'objets particuliers.
  2. Ce que nous allons voir à présent, les méthodes d'instance. Elles sont définies pour tous les objets du type de cette classe (utilisables par toutes les instances). Pour les utiliser nous devons les appliquer à un objet du bon type.

Méthode d'instance

Déclaration d'une méthode d'instance

Exemple
class Ordinateur
  def boot
    puts "Start..."
  end

  def shutdown
    puts "Extinction."
  end
end
Fin de l'exemple


Nous avons ici une classe Ordinateur. Cette classe définit deux méthodes : boot et shutdown, disponibles pour les objets de type Ordinateur. Comme vous pouvez le voir, la seule nouveauté est qu’elles sont définies à l'intérieur d'une classe (entre les mots-clés class et end).

Appel d'une méthode d'instance

Tout d’abord, instancions un objet de type Ordinateur :

Exemple
laptop = Ordinateur.new
Fin de l'exemple


Les méthodes définies plus haut s'appliquent à une instance d'objet. Nous devons donc, dans notre exemple, les invoquer sur l'instance laptop en suivant le modèle : instance.méthode.

Ce qui nous donne donc :

Exemple
laptop.boot # appel de la méthode boot
laptop.shutdown # appel de la méthode shutdown
Fin de l'exemple


Mise à part cette nouveauté, les anciennes possibilités demeurent : vous pouvez passer des paramètres et récupérer une valeur de retour (pour l’utiliser dans une autre expression par exemple).

L'héritage

L'orientation objet de Ruby permet de faire hériter certaines classes d'autres classes. C'est là qu'intervient la notion de sous-classe. Cet exemple simple montre comment définir une classe héritant d'une super-classe :

Exemple
class Machine
  #
end

class Ordinateur < Machine # Ordinateur hérite de Machine
  #
end
Fin de l'exemple


Dans la définition de la classe Ordinateur, < Machine indique que cette classe est une sous-classe de la classe Machine.

Propriété

Par défaut, les sous-classes héritent des méthodes de leur super-classe : elles ont le même comportement. Mais l’intérêt est que vous pouvez vous servir des sous-classes pour modifier des méthodes ou en ajouter de nouvelles.


On pourrait donc enrichir notre classe Ordinateur pour lui rajouter des méthodes par rapport à sa super-classe Machine. L'héritage permet de spécialiser différemment des classes ayant un même tronc commun.

Propriété

Vous pouvez modifier une classe (pour y ajouter des méthodes, par exemple) sans disposer de son code d'origine.


La méthode initialize

Propriété

Lors de l'instanciation d'un nouvel objet (appel de new), l'interpréteur vérifie si une méthode initialize est associée à cet objet. Si c’est le cas il l'exécute.


Exemple
class Ordinateur
  def initialize
    puts "Nouvel ordinateur !"
    self.run
  end

  def run
    puts "Hello world !"
  end
end

monOrdi = Ordinateur.new
# => Nouvel ordinateur !
# => Hello world !
Fin de l'exemple


Propriété

La méthode initialize est appelée dès l'instanciation.


La méthode initialize est presque une méthode comme les autres, elle peut prendre des paramètres, mais elle ne renvoie pas de valeur (enfin, elle renvoie une référence à l’objet instancié mais ce n’est pas exploitable).

Définition

Le mot-clé self fait référence à l’objet qui appelle la méthode (ici monOrdi).


Donc écrire self.run (à l'intérieur de la classe) équivaut à écrire monOrdi.run (à l'extérieur de la classe).

Propriété

self est implicite (par exemple, run est équivalent à self.run).


Dans d'autres langages, il y a un équivalent à la méthode initialize, ce sont des constructeurs qui portent le même nom que la classe (en Java, par exemple).

Propriété

Si la méthode initialize n'a pas été trouvée dans la définition de la classe, l'interpréteur en cherche une dans les super-classes de la classe en question.


Exemple
class GrandParent
  def initialize
    puts "visite :o)"
  end
end

class Parent < GrandParent; end # sous-classe de GrandParent
class Enfant < Parent; end # sous-classe de Parent

me = Enfant.new # => visite :o)
Fin de l'exemple


Ici, la classe Enfant ne dispose pas d'une méthode initialize, on inspecte sa super-classe Parent ; elle n'en possède pas non plus, on va regarder du côté de sa super-classe GrandParent ; on appelle la méthode initialize de la classe GrandParent.

Redéfinition de méthodes

Définition

On peut redéfinir une méthode pour en modifier le comportement.


Propriété

Vous pouvez redéfinir des méthodes même si vous ne disposez pas du code de la classe. Toutes les méthodes peuvent être redéfinie, initialize ne fait pas exception. La redéfinition peut aussi servir à différencier une méthode d'une sous-classe héritée de sa super-classe.


Voici par exemple deux classes : Machine et Ordinateur, la seconde héritant de la première :

Exemple
class Machine
  def run
    puts "je suis une machine"
  end
end

class Ordinateur < Machine
  def run # on redéfinit la méthode run héritée de Machine
    puts "je suis un ordinateur donc une machine"
  end
end

objet1 = Machine.new
objet2 = Ordinateur.new

objet1.run # méthode originelle
objet2.run # méthode redéfinie
Fin de l'exemple


En invoquant la méthode run sur l’objet de type Machine, nous obtenons l’affichage produit par la méthode de la super-classe Machine. La méthode redéfinie a été appelée lorsque nous avons invoqué run sur l’objet de type Ordinateur.

Appel de méthode de super-classe

Considérons deux classes Machine et Ordinateur (sous-classe de Machine) disposant toutes deux d'une méthode run :

Exemple
class Machine
  def run
    puts "une machine"
  end
end

class Ordinateur < Machine
  def run
    print "je suis un ordinateur donc "
    super
  end
end
Fin de l'exemple


Définition

Le mot-clé super, placé au sein d'une méthode, nous permet d'appeler la méthode du même nom dans la super-classe. super peut être placé n’importe où dans la déclaration de votre méthode, et autant de fois que vous le voulez.


Ici, super appelle la méthode run de la classe Machine.

Il appelle la méthode de la super-classe avec exactement les mêmes paramètres que la méthode dans laquelle il se trouve (dans notre exemple, il n'y en a aucun). Nous pouvons aussi choisir de n'en passer que quelques-uns, ou bien aucun. Dans ce dernier cas, l'appel à super doit être suivi d'une paire de parenthèses vides :

Exemple
def run(prix, poids)
  super(poids) # seul le second paramètre est passé
  super() # aucun paramètre n'est passé
end
Fin de l'exemple


Conclusion

Dans la documentation, vous trouverez des méthodes désignées comme suit :

NomClasse#Méthode

Cela vous permet de savoir sur quel type d'objet vous pouvez invoquer la méthode.

Par exemple : Integer#upto vous informe qu’il existe une méthode upto applicable à des objets de type Integer (les entiers).

Cet article est issu de Wikiversity. Le texte est sous licence Creative Commons - Attribution - Partage dans les Mêmes. Des conditions supplémentaires peuvent s'appliquer aux fichiers multimédias.