Ruby orienté objet
Ruby est un langage purement orienté objet, et tout dans Ruby prend la forme d'objets. Chaque valeur en Ruby est un objet, même les choses les plus primitives : les chaînes de caractères, les nombres, et même true et false sont des objets. La classe elle-même est aussi unobjet, qui estClassune instance de la classe Class. Ce chapitre expliquera toutes les principales fonctionnalités liées à la programmation orientée objet en Ruby.
Les classes sont utilisées pour spécifier la forme des objets. Elles combinent la représentation des données et les méthodes, en organisant les données dans un ensemble bien organisé. Les données et les méthodes d'une classe sont appelées membres de la classe.
Définition de classe Ruby
Lorsque vous définissez une classe, vous définissez en réalité un plan pour un type de données. Cela ne définit pas réellement de données, mais définit plutôt ce que signifie le nom de la classe, c'est-à-dire de quoi seront constitués les objets de la classe et quelles opérations pourront être effectuées sur l'objet.
Une définition de classe commence par le mot-cléclasset est suivie parle nom de la classe, et se termine enfin parendun séparateur pour marquer la fin de la définition de la classe. Par exemple, nous utilisons le mot-clé class pour définir la classe Box, comme montré ci-dessous :
Par convention, le nom doit commencer par une lettre majuscule. S'il contient plusieurs mots, mettez en majuscule la première lettre de chaque mot, mais sans séparateur entre eux (par exemple, CamelCase).
Définition d'objets Ruby
Les classes fournissent le plan pour les objets, donc en gros, les objets sont créés à partir de la classe. Nous utilisons lenewmot-clé pour déclarer des objets de la classe. L'instruction suivante déclare deux objets de la classe Box :
La méthode initialize
initializeLa méthode est une méthode de classe Ruby standard, servant de constructeur de classe, et est similaire auconstructeurprincipe de fonctionnement dans d'autres langages de programmation orientés objet. Lorsque vous voulez initialiser certaines variables de classe lors de la création d'un objet, la méthode initialize est utile. Cette méthode prend une série de paramètres ; comme les autres méthodes Ruby, lorsque vous l'utilisez, vous devez placer ledefmot-clé avant celui-ci, comme montré ci-dessous :
Variables d'instance
Les variables d'instancesont des attributs de classe. Lorsque des objets sont créés à l'aide de la classe, elles deviennent les attributs des objets. Les attributs de chaque objet sont assignés séparément et ne partagent pas leurs valeurs avec d'autres objets. À l'intérieur de la classe, ces attributs sont accessibles à l'aide de l'opérateur @ ; à l'extérieur de la classe, ils sont accessibles à l'aide de méthodes appeléesméthodes d'accès, qui sontdesméthodes publiques. Ci-dessous, nous prenons la classe définie ci-dessusBoxcomme exemple, et utilisons @width et @height comme variables d'instance de la classe Box.
Méthodes d'accès (getter) et de modification (setter)
Pour lire des variables définies dans une classe depuis l'extérieur de la classe, nous pouvons définir des méthodes d'accès (getter) pour y accéder. L'exemple suivant illustre l'utilisation des méthodes d'accès :
Exemple
Essayez-le »
Lorsque le code ci-dessus est exécuté, il produit le résultat suivant :
盒子宽度 : 10 盒子高度 : 20
Comme les méthodes d'accès utilisées pour accéder aux valeurs des variables, Ruby permet de transmettre des paramètres aux variables définies dans une classe depuis l'extérieur de la classe, ce que l'on appelle lesméthodes d'assignation, définies comme suit :
Exemple
Essayez-le »
Lorsque le code ci-dessus est exécuté, il produit le résultat suivant :
盒子宽度 : 30 盒子高度 : 50
Comme ces deux méthodes sont très couramment utilisées, Ruby définitattr_accessor :variable_name、attr_reader :variable_name、attr_writer :variable_nametrois méthodes de déclaration d'attributs. Parmi elles :accesseur=lecteur+écrivain。
Remarque : le nom de la variable doit être précédé de:, et entre les noms de variables, utilisez,pour les séparer.
Méthodes d'instance
Les méthodes d'instancesont définies de la même manière que les autres méthodes, en utilisant le mot-clédef, mais elles ne peuvent être utilisées que via des instances de classe, comme le montre l'exemple ci-dessous. Leurs fonctions ne se limitent pas à accéder aux variables d'instance ; elles peuvent également effectuer de nombreuses autres tâches selon les besoins.
Exemple
Essayez-le »
Lorsque le code ci-dessus est exécuté, il produit le résultat suivant :
Area of the box is : 200
Méthodes de classe et variables de classe
Variables de classesont des variables partagées par toutes les instances d'une classe. En d'autres termes, les variables de classe sont accessibles par toutes les instances d'objet. Les variables de classe sont préfixées par deux caractères @ (@@). Les variables de classe doivent être initialisées dans la définition de la classe, comme montré dans l'exemple ci-dessous.
Méthodes de classesont définies à l'aide dudef self.methodname()mot-clé, et les méthodes de classe se terminent par le délimiteur end. Les méthodes de classe peuvent être appelées en utilisant laclassname.methodnameforme avec le nom de la classe, comme montré dans l'exemple ci-dessous :
Exemple
Essayez-le »
Lorsque le code ci-dessus est exécuté, il produit le résultat suivant :
Box count is : 2
La méthode to_s
Toute classe que vous définissez possède une méthode d'instanceto_spour renvoyer la représentation sous forme de chaîne de l'objet. Voici un exemple simple représentant des objets Box en fonction de la largeur et de la hauteur :
Exemple
Essayez-le »
Lorsque le code ci-dessus est exécuté, il produit le résultat suivant :
String representation of box is : (w:10,h:20)
Contrôle d'accès
Ruby vous offre trois niveaux de protection des méthodes d'instance, à savoirpublic, private ou protected. Ruby n'applique aucun contrôle d'accès aux variables d'instance et de classe.
- Méthodes publiques :Les méthodes publiques peuvent être appelées par n'importe quel objet. Par défaut, les méthodes sont publiques, sauf la méthode initialize, qui est toujours privée.
- Méthodes privées :Les méthodes privées ne peuvent pas être accessibles ni consultées depuis l'extérieur de la classe. Seules les méthodes de classe peuvent accéder aux membres privés.
- Méthodes protégées :Les méthodes protégées ne peuvent être appelées que par des objets de la classe et de ses sous-classes. L’accès ne peut également se faire qu’à l’intérieur de la classe et de ses sous-classes.
Voici un exemple simple illustrant la syntaxe de ces trois modificateurs :
Exemple
Essayez-le »
Lorsque le code ci-dessus est exécuté, il produit le résultat suivant. Ici, le premier appel de méthode réussit, mais le second appel de méthode pose un problème.
Area of the box is : 200 test.rb:42: protected method `printArea' called for # <Box:0xb7f11280 @height=20, @width=10> (NoMethodError)
Héritage de classe
L'héritage est l'un des concepts les plus importants de la programmation orientée objet. L'héritage nous permet de définir une classe à partir d'une autre classe, ce qui facilite la création et la maintenance des applications.
L'héritage facilite la réutilisation du code et une exécution rapide. Malheureusement, Ruby ne prend pas en charge l'héritage multiple, mais Ruby prend en chargemixinsmixins. Les mixins sont comme une implémentation spécifique de l'héritage multiple, où seule la partie interface est héritable.
Lors de la création d'une classe, le programmeur peut spécifier directement que la nouvelle classe hérite des membres d'une classe existante, évitant ainsi d'écrire de nouveaux membres de données et fonctions membres à partir de zéro. Cette classe existante est appeléeclasse de base ou classe parente, et la nouvelle classe est appeléeclasse dérivée ou sous-classe。
Ruby fournit également le concept de sous-classement, qui est l'héritage. L'exemple suivant explique ce concept. La syntaxe pour étendre une classe est très simple. Ajoutez simplement un caractère < et le nom de la classe parente à l'instruction class. Par exemple, ce qui suit définit la classeBigBoxest uneBoxsous-classe :
Exemple
Essayez-le »
Lorsque le code ci-dessus est exécuté, il produit le résultat suivant :
Big box area is : 200
Surcharge de méthode
Bien que vous puissiez ajouter de nouvelles fonctionnalités dans une classe dérivée, vous pouvez parfois vouloir modifier le comportement d'une méthode déjà définie dans la classe parente. Dans ce cas, vous pouvez conserver le nom de la méthode inchangé et redéfinir la fonctionnalité de la méthode, comme illustré dans l'exemple suivant :
Exemple
Essayez-le »
La sortie de l'exemple ci-dessus est :
Big box area is : 200
Surcharge des opérateurs
Nous voulons utiliser l'opérateur + pour effectuer l'addition vectorielle de deux objets Box, utiliser l'opérateur * pour multiplier la largeur et la hauteur de Box, et utiliser l'opérateur unaire - pour inverser le signe de la largeur et de la hauteur de Box. Voici une version de la classe Box avec des définitions d'opérateurs mathématiques :
Gel des objets
Parfois, nous voulons empêcher les objets d'être modifiés. Dans Object, la méthode freeze peut y parvenir, transformant effectivement un objet en constante. Tout objet peut être gelé en appelantObject.freezefreeze. Un objet gelé ne peut pas être modifié, c'est-à-dire que vous ne pouvez pas modifier ses variables d'instance.
Vous pouvez utiliser la méthodeObject.frozen?pour vérifier si un objet donné a été gelé. Si l'objet est gelé, cette méthode renvoie true ; sinon, elle renvoie une valeur false. L'exemple suivant explique ce concept :
Exemple
Essayez-le »
Lorsque le code ci-dessus est exécuté, il produit le résultat suivant :
Box object is frozen object
test.rb:20:in `setWidth=': can't modify frozen object (TypeError)
from test.rb:39
Constantes de classe
Vous pouvez définir une constante à l'intérieur d'une classe en affectant directement une valeur numérique ou une chaîne à une variable. Les constantes n'ont pas besoin d'utiliser @ ou @@. Par convention, les noms des constantes sont en majuscules.
Une fois qu'une constante est définie, vous ne pouvez pas modifier sa valeur. Vous pouvez accéder à la constante directement à l'intérieur de la classe, comme pour accéder à une variable, mais si vous souhaitez accéder à la constante en dehors de la classe, vous devez utiliserclassname::constant::, comme indiqué dans l'exemple suivant.
Exemple
Essayez-le »
Lorsque le code ci-dessus est exécuté, il produit le résultat suivant :
Area of the box is : 200 TATA Inc Box weight is: 10
Les constantes de classe peuvent être héritées et peuvent aussi être redéfinies comme les méthodes d'instance.
Création d'objets en utilisant allocate
Il peut arriver que vous souhaitiez créer un objet sans appeler le constructeur d'objetinitialize, c'est-à-dire sans utiliser la méthode new pour créer un objet. Dans ce cas, vous pouvez appeler allocate pour créer un objet non initialisé, comme le montre l'exemple suivant :
Exemple
Essayez-le »
Lorsque le code ci-dessus est exécuté, il produit le résultat suivant :
Area of the box is : 200 test.rb:14: warning: instance variable @width not initialized test.rb:14: warning: instance variable @height not initialized test.rb:14:in `getArea': undefined method `*' for nil:NilClass (NoMethodError) from test.rb:29
Informations sur la classe
Le self de Ruby et le this de Java présentent des similitudes, mais sont aussi assez différents. En Java, les méthodes sont référencées dans les méthodes d'instance, donc this pointe généralement vers l'objet courant. Le code Ruby s'exécute ligne par ligne, donc self a des significations différentes selon le contexte. Regardons l'exemple suivant :
Exemple
Essayez-le »
Lorsque le code ci-dessus est exécuté, il produit le résultat suivant :
Class of self = Class Name of self = Box
Cela signifie que la définition de classe peut être exécutée en traitant la classe comme l'objet courant, et cela signifie aussi que les méthodes de la métaclasse et de la classe parente sont disponibles pendant l'exécution de la définition de méthode.
Autres extensions