Programmation Orientée Objet
Classes
Création et instanciation d’une classe
Un classe se crée à l’aide du mot clé class puis s’instencie avec la méthode new.
class MaClasse
...
end
object = MaClasse.new
puts object.inspect #<MaClasse:id>Variables d’instance et constructeur
En Ruby, les variables d’instance sont symbolisées par un @ et sont définit directement au niveau du constructeur, lui-même définit avec la méthode initialize.
class MaClasse
def initialize(var1, var2)
@var1 = var1
@var2 = var2
end
endMéthodes d’instance
Les méthodes d’instance se définissent au sein de la classe comme des méthodes classiques et suivent les même conventions. (nommage, ? si renvoie booléen, ! si modifie l’objet…)
class MaClasse
def une_methode
<instructions>
end
end
object = MaClasse.new
object.une_methodeIl est possible d’appeler une autre méthode d’instance depuis une méthode comme on appellerait une fonction depuis l’exterieur de la classe. (Pas de this)
class MaClasse
def une_methode(var)
<instructions>
end
def une_autre_methode
<instructions>
une_methode(var)
<instructions>
end
endSetter et Getter
- Methode naïve
class MaClasse
def initialize(var)
@var = var
end
def var()
@var
end
def var=(var)
@var = var
end
end
object = MaClasse.new
object.var = "test"
puts object.var- Utilisation de
attr_accessor,attr_readeretattr_writer
class MaClasse
attr_accessor :var
def initialize(var)
@var = var
end
end
object = MaClasse.new
object.var = "test"
puts object.varCes 3 méthodes sont en fait des méthodes de classes qui permettent de créer les getter et setter qui est appelée statiquement à l’intérieur de la classe.
Méthodes privées
Les méthodes privées doivent être déclarées après le mot-clé private. Elles restent accessibles à l’intérieur de la classe.
class MaClasse
private
def une_methode(var)
<instructions>
end
endMéthodes et Variables de classe
- Méthodes de classe
Les méthodes de classe ne sont pas rattachées à une instance de la classe et se déclarent avec le mot-clé self.
class MaClasse
def self.methode_classe
<instructions>
end
end
puts MaClasse.methode_classePour appeler une méthode de classe depuis une méthode d’instance, il faut utiliser self.class.<nom_methode>.
class MaClasse
def self.methode_classe
<instructions>
end
def une_methode
self.class.methode_classe
end
end- Variables de classe
Les variables de classe se déclarent avec @@. Dans les méthodes de classe ou d’instance, on accède toujours aux variables de classe directement.
class MaClasse
@@variable_classe = 'test'
def self.methode_classe
"#{@@variable_classe}"
end
def une_methode
"#{@@variable_classe}"
end
end
puts MaClasse.methode_classeOuverture des classes
En Ruby, les classes restent toujours ouvertes, il est donc possible de les modifier après leur déclaration.
Soit en créant une méthode de classe à l’exterieur de celle-ci :
class MaClasse
def une_methode
<instructions>
end
end
def MaClass.methode_classe
<instructions>
endSoit en réutilisant la même déclaration :
class MaClasse
def une_methode
<instructions>
end
end
class MaClasse
def self.methode_classe
<instructions>
end
endIl est ainsi possible de “modifier” les méthodes internes à Ruby comme les méthodes de la classe String par exemple…
Méthodes “spéciales” et opérateurs
- methode
class
La méthode class, appelée sur un objet, renvoie le Class de cet objet.
s = "Ceci est un texte"
s.class # String<et>
Il est possible d’implémenter les opérateurs de supériorité et d’infériorité sur des objets en définissant ces méthodes qui prennent chacune l’élément sur lequel s’applique la comparaison :
class MaClass
def <(elem)
<instructions>
end
endL’héritage
L’héritage se fait en Ruby avec le symbole <.
class BaseClass
...
end
class HeritedClass < BaseClass
...
endAinsi, HeritedClass “hérite” de toutes les méthodes et tous les attributs de BaseClass. Et il est aussi possible d’en ajouter de nouveaux ou de les surcharger. Dans ce cas, la méthode parente est accessible via le mot-clé super.
En Ruby, super correspond bien à la méthode parente et non à l’objet parent. De plus, utiliser super appelle la méthode (par défaut, avec les même paramètres que la méthode surchargée).
class HeritedClass < BaseClass
def method(param)
method_value = super # équivalent : method_value = super(param)
other_method_value = super(other_param)
...
end
endDe la même manière que la méthode class, appeler class.superclass donne des informations sur la classe de base. Si on remonte dans la hiérarchie, toutes les classe de base héritent de Object qui, elle-même, hérite de BaseObject.
Les exceptions
- Lancement d’une exception
En Ruby, une exception se lève avec la méthode raise.
def method
raise if error # unhandled exception
raise "Il y a une erreur" if error # RuntimeError avec message
raise SpecificError "Il y a une erreur" if error # SpecificError avec message
end- Capture d’une exception
Une exception peut être capturer entre un begin et un rescue (qui prend en paramètre le type d’exception qu’on veut capturer) :
begin
method
rescue SpecificError => e
puts e.to_s
end- Execution de code même si erreur
Le mot-clé ensure permet d’exécuter du code même si une exception a été capturée :
begin
method
rescue SpecificError => e
puts e.to_s
ensure
<instructions>
end- Créer une classe d’erreur
class MonErreur < RuntimeError
def initialize(msg = "Message par défaut")
super
end
end
def method
raise MonErreur if error
endEn général, on ne fait pas hériter les classes d’erreur de RuntimeError mais on crée une classe Error pour le module, qui hérite de RuntimeError, et ensuite les classes d’erreur héritent de cette Error. Cela permet de capturer en une seule fois toutes les erreurs possibles pour le module en question au niveau du rescue :
module MonModule
class Erreur < RuntimeError
end
class PremiereErreur < Erreur
def initialize(msg = "Message par défaut")
super
end
end
class DeuxiemeErreur < Erreur
def initialize(msg = "Message par défaut")
super
end
end
def method
raise PremiereErreur if error1
raise DeuxiemeErreur if error2
end
end
begin
MonModule::method
rescue MonModule::Erreur => e
puts e.to_s
end