À l'issue de ce chapitre, l'étudiant sera capable de :
virtual / override)operator)La programmation orientée objet (POO) repose sur quatre piliers :
Analogie : La classe Voiture est le plan de fabrication. Chaque voiture produite (ma voiture, ta voiture) est un objet (instance).
| Modificateur | Visibilité |
|---|---|
public | Accessible partout |
private | Accessible uniquement dans la classe (par défaut) |
protected | Accessible dans la classe et ses classes dérivées |
Important : chaque objet possède sa propre copie des attributs. Modifier e1.Nom n'affecte pas e2.Nom.
Écrivez un programme qui :
Produit avec les attributs : Nom (string), Prix (double), Quantite (int)ValeurStock() qui retourne Prix * QuantiteAfficher() qui affiche les détails du produitChaque objet a sa propre copie de Valeur. a est incrémenté 3 fois, b une seule fois.
Sortie : 3 1
private et à fournir des propriétés (get / set) pour contrôler l'accès et protéger les données.
Problème sans encapsulation :
Solution : rendre les attributs private et exposer des propriétés avec validation.
Écrivez une classe Employe avec :
Nom (string)Salaire (double) : refuser les valeurs négativesSalaireAnnuel qui retourne Salaire * 12Afficher() qui affiche nom, salaire mensuel et annuelTestez avec un employé et tentez d'affecter un salaire négatif.
Taille = 5 → accepté (5). Taille = -3 → refusé (reste 5). Taille = 10 → accepté (10).
Sortie : 10
this et chaînagethisthis désigne l'objet courant. Il sert à lever l'ambiguïté entre un paramètre et un attribut de même nom.
this(...)Écrivez une classe Cercle avec :
Rayon (double)Surface() qui retourne π × r²Perimetre() qui retourne 2 × π × rCréez deux cercles (avec et sans paramètre) et affichez leurs mesures.
p1 utilise le constructeur par défaut qui chaîne vers (0,0). p2 utilise (3,7).
Sortie : (0,0) (3,7)
baseLe constructeur de la classe dérivée doit appeler le constructeur de la classe de base à l'aide de base(...).
Écrivez :
Forme avec une propriété Couleur (string) et un constructeur paramétréRectangle héritant de Forme, avec Largeur et Hauteur, et une méthode Surface()Cercle héritant de Forme, avec Rayon, et une méthode Surface()Les constructeurs s'exécutent du parent vers l'enfant : d'abord A, puis B, puis C.
Sortie : A B C
virtual et overridevirtual, et la classe dérivée la redéfinit avec override.
Le polymorphisme prend tout son sens lorsqu'on manipule des objets via une référence de type base :
Point clé : bien que la variable soit de type Forme, c'est la méthode Surface() de la classe réelle (Rectangle ou Cercle) qui est exécutée. C'est la liaison tardive (late binding).
virtual vs pas de virtual| Scénario | Comportement |
|---|---|
virtual + override | Méthode de la classe réelle appelée (polymorphisme) |
Sans virtual | Méthode de la classe de la variable appelée (liaison statique) |
Écrivez :
Animal avec une propriété Nom et une méthode virtual string Cri() retournant "..."Chat (retourne "Miaou"), Chien (retourne "Ouaf"), Vache (retourne "Meuh")Animal[] contenant un chat, un chien et une vache"Nom dit Cri"Grâce au polymorphisme, c'est le type réel qui détermine la méthode : a est un Y, b et c sont des Z.
Sortie : Y Z Z
Attention : ne pas confondre surcharge (overloading = même classe, signatures différentes) et redéfinition (overriding = classe dérivée, virtual/override).
Écrivez une classe Convertisseur avec des méthodes surchargées Convertir :
Convertir(double celsius) → retourne la température en Fahrenheit (C × 9/5 + 32)Convertir(double valeur, string unite) → si unite == "km" retourne la valeur en miles (× 0.621), sinon retourne la valeur en km (× 1.609)Convertir(int minutes) → retourne une chaîne formatée "Xh Ymin"Testez chaque variante.
F(5) appelle F(int), F(3.14) appelle F(double), F(2,8) appelle F(int,int).
Sortie : int:5 → double:3.14 → deux:10
+, -, ==, etc.) pour une classe personnalisée. La méthode doit être public static et utiliser le mot-clé operator.
| Catégorie | Opérateurs |
|---|---|
| Arithmétiques | + - * / % |
| Comparaison (par paires) | == != | < > | <= >= |
| Unaires | + - ! ++ -- |
Règle : les opérateurs de comparaison doivent être surchargés par paires : si vous surchargez ==, vous devez aussi surcharger !=.
== et !=Sans surcharge de ==, la comparaison vérifie si les deux variables pointent vers le même objet en mémoire (référence), et non si les valeurs sont égales.
Écrivez une classe Fraction (Numérateur, Dénominateur) avec :
+ : addition de deux fractions (a/b + c/d = (a*d + c*b) / (b*d))* : multiplication (a/b * c/d = (a*c) / (b*d))ToString() pour afficher sous la forme "Num/Den"Testez avec 1/2 + 1/3 et 2/3 * 3/4.
c = 2.5 + 3.0 = 5.5. a > b : 2.5 > 3.0 = false. a < b : 2.5 < 3.0 = true.
Sortie : 5.5 → False → True
| Concept | Mot-clé | Description |
|---|---|---|
| Classe / Objet | class, new |
Modèle et instance concrète |
| Encapsulation | private, get, set |
Contrôle de l'accès aux données |
| Constructeur | this |
Initialisation à la création de l'objet |
| Héritage | :, base |
Réutilisation de la classe de base |
| Polymorphisme | virtual, override |
Comportement variable selon le type réel |
| Surcharge de méthodes | — | Même nom, signatures différentes |
| Surcharge d'opérateurs | operator |
Redéfinir +, -, ==, etc. |
get/setthis):, base)virtual dans la classe de baseoverride dans la classe dérivéepublic static operator==/!=)sealed)is, as)