|
|
|
|
TUTORIEL OUTILS |
|
|
|
La gestion Objet au sein du langage Ruby |
L'approche des classes et de l'héritage par Ruby peut surprendre, mais révèle un langage très élégant et logique dans ses approches.
(18/11/2005) |
|
Nous l'avions déjà précisé
à propos de la syntaxe (lire notre
article du 25/08/05), Ruby est un langage "tout Objet"
: un simple chiffre représente en fait une occurrence de la
classe Integer (Fixnum, ou Bignum
pour les grands nombres). Nous allons donc voir comme Ruby
présente la gestion Objet au développeur...
Ruby a été conçu pour offrir un support Objet à la fois complet
et extensible - on pourra par exemple ajouter des méthodes à
une occurrence de classe sans que les autres occurrences soient
affectées.
Classes
Nous avons déjà vu comment utiliser les méthodes existantes. Par exemple, la classe Integer
fournit un méthode next, qui
pourra s'appeller sous ces formes :
puts 1.next # affiche la
valeur 2
puts 1.next.next # affiche la valeur 3
Nous avions également vu comment ajouter des méthodes aux classes
:
class Float
def jeMange
"Vous ne voyez pas que je mange ?"
end
end
puts 3.14159265.jeMange
# affiche le chaîne "Vous ne voyez pas que je mange ?"
Cela nous présente par la même occasion la méthode de création
de classe personnelle : plutôt que d'ajouter des méthodes à
des classes existantes, il peut être plus pratique de se créer
ses propres classes, en rapport avec le contexte de l'application.
Par exemple, si nous devons gérer un lecteur MP3 :
class
LecteurMP3
def chargerFichier(chemin, fichier)
# ...
end
def jouerFichier(fichier)
# ...
end
def fermerFichier(fichier)
# ...
end
end
À partir de là, on pourra instancier notre classe en un objet
spécifique :
monLecteur = LecteurMP3.new('lapin')
monLecteur.chargerFichier('/musique', 'stfu.ogg')
monLecteur.jouerFichier('stfu.ogg')
Le constructeur d'une classe Ruby ne se créé pas en ayant une
méthode du même nom que la classe, mais au travers d'une méthode
à part, initalize. Celle-ci
peut prendre en compte certains arguments clefs, et est généralement
utilisée pour assigner ces arguments à des variables d'instance
(c'est à dire, des variables propres à l'objet, ou plus simplement
ses attributs) :
class LecteurMP3
def initialize(chemin)
@chemin = chemin
@lectureEnCours = false
puts 'Bienvenue dans LecteurMP3 v0.0.1.0'
end
def chargerFichier(fichier)
leChemin = @chemin + fichier
...
monLecteur = LecteurMP3.new('lapin')
monLecteur.chargerFichier('stfu.ogg')
initialize est donc appellé
à chaque instanciation de LecteurMP3. Le caractère @,
placé devant un nom de variable, indique que celle-ci est une
variable d'instance.
Héritage
Comme tout bon langage orienté Objet, Ruby autorise l'héritage,
afin de dériver et spécialiser les classes. Il faut savoir que
Ruby n'autorise que l'héritage simple, comme Java, c'est-à-dire
qu'une classe ne peut hériter que d'une seule autre classe (à
la différence de l'héritage multiple). C'est une conception
voulue, et l'héritage multiple peut être suppléé par des modules,
ou "mixins", c'est-à-dire des groupements de méthodes.
Voyons déjà comment entreprendre l'héritage :
class Femme < Humain
def initalize(prenom, nom, dateNaissance)
super(prenom, nom, dateNaissance)
@sexe = f
end
...
Le signe "plus petit que" fait ici office de "flèche" pour indiquer
que Femme descend de Humain, et donc récupère ses méthodes.
Grâce à super(), on passe certains
arguments à la méthode initialize
de la classe parente, afin qu'ils soient correctement traités.
Les modules diffèrent des classes en cela que les méthodes qu'ils
contiennent ne forment pas naturellement une classe. Les méthodes
d'une classe ont toutes la classe en commun, une sorte de contexte
global qui les relie. Les modules peuvent de leur côté contenir
toutes sortes de méthodes, sans qu'elles soient forcément liées.
Les modules ne peuvent pas être instanciés.
module Zorglub
CONSTANTE = 42
def Zorglub.uneFonction
# ...
end
end
Le module a l'avantage, face à un simple fichier externe de
codes variés, de fournir un espace de nom unique aux fonctions
qu'il contient. Cela permet d'éviter le cas où deux groupes
de méthodes chargés entrent en conflit pour cause de noms de
méthodes identiques.
require zorglub
laReponse = Zorglub::CONSTANTE
bidule = Zorglub.uneFonction
Les modules peuvent suppléer efficacement à l'héritage multiple
par le biais de "mixins". Un module ne peut être instancié,
mais il peut être appelé directement depuis le corps d'une classe,
ce qui fournit l'ensemble de ses méthodes à la classe appelante.
Dans les faits, les modules "ajoutés" à une classe se comportent
de la même manière que le ferait une super normale. Il devient
donc possible de définir des méthodes d'instance au sein d'un
module.
class GrandMechantEvilGrave
include Zorglub
# ...
end
Ainsi, tout en restant un langage à héritage simple, Ruby peut
profiter de manière élégante de tous les avantages de l'héritage
multiple. |
|
|
|
|
|
Quand achetez-vous le plus en ligne ? |
|
|
|
|
|
|
|
|