L'héritage en C# - Concepts de base
L'héritage permet de créer une nouvelle classe (dérivée) à partir d'une classe existante (de base).
Atome 1 : L'Héritage "Passif" (Le Cadeau)
Objectif : Constater que la classe dérivée "reçoit" gratuitement les fonctionnalités de sa classe de base. On n'utilise aucun constructeur ici pour se concentrer sur le lien.
classDiagram
class Vehicule {
+«get»+«set» Marque:string
}
class Voiture {
+«get»+«set» NbPortes:int
}
Vehicule <|-- Voiture : est un
public class Vehicule
{
private string _marque;
public string Marque
{
get => _marque;
set => _marque = value;
}
// ...
}
// L'utilisation du ":" crée le lien "Est un"
public class Voiture : Vehicule
{
private int _nbPortes;
public int NbPortes
{
get => _nbPortes;
set => _nbPortes = value;
}
// ...
}
Sentiment d'efficacité
Même si la classe Voiture est presque vide, une instance de voiture possède maintenant une propriété Marque. Vous avez réutilisé du code sans l'écrire.
Atome 2 : La Redéfinition (Le Droit de Parole)
Objectif : Apprendre à modifier un comportement existant. La classe de base donne la permission (virtual), la classe dérivée prend la parole (override).
classDiagram
class Vehicule {
+«virtual» Klaxonner() void
}
class Camion {
+«redefine» Klaxonner() void
}
Vehicule <|-- Camion
public class Vehicule
{
// "virtual" = "Je vous autorise à changer ce comportement"
public virtual void Klaxonner()
{
Console.WriteLine("Bip bip !");
}
}
public class Camion : Vehicule
{
// "override" = "Je prends la parole et je change le comportement"
public override void Klaxonner()
{
Console.WriteLine("POUÊÊÊÊÊT !");
}
}
Atome 3 : Le mot-clé base (La Taxe de Construction)
Objectif : Comprendre comment initialiser la classe de base quand elle possède un constructeur avec des paramètres. On utilise les propriétés pour valider les données dès la construction.
classDiagram
class Vehicule {
+«get»-«set» Marque:string
+«create» Vehicule(marque:string)
}
class Voiture {
+«get»-«set» NbPortes:int
+«create» Voiture(marque:string, nbPortes:int)
}
Vehicule <|-- Voiture
public class Vehicule
{
private string _marque;
public Vehicule(string marque)
{
// On passe par la propriété pour forcer la validation
Marque = marque;
}
public string Marque
{
get => _marque;
private set
{
// Validation moderne (.NET 8+)
// Note : Le message est standardisé pour inclure le nom du paramètre
ArgumentNullException.ThrowIfNullOrEmpty(value);
_marque = value;
}
}
}
public class Voiture : Vehicule
{
private int _nbPortes;
public Voiture(string marque, int nbPortes) : base(marque)
{
// On passe par la propriété pour forcer la validation
NbPortes = nbPortes;
}
public int NbPortes
{
get => _nbPortes;
private set
{
// Validation manuelle de la plage
if (value < 2 || value > 5)
{
throw new ArgumentOutOfRangeException(nameof(value), "Le nombre de portes doit être compris entre 2 et 5.");
}
_nbPortes = value;
}
}
}
Atome 4 : Le Polymorphisme (L'Étiquette vs La Boîte)
Objectif : Comprendre qu'une variable (l'étiquette) peut être d'un type plus général que l'objet réel (la boîte).
// L'étiquette dit "Vehicule", mais la boîte est une "Voiture"
Vehicule monAuto = new Voiture("Toyota", 4);
monAuto.Klaxonner(); // Le système regarde DANS la boîte pour savoir comment klaxonner.
// Console.WriteLine(monAuto.NbPortes); // IMPOSSIBLE : l'étiquette Vehicule ne connaît pas cette propriété.
Attention au regard
Si votre étiquette dit Vehicule, vous ne pouvez pas voir les options spécifiques à la Voiture (comme NbPortes), même si elles sont dans la boîte. Vous ne voyez que ce qui est écrit sur l'étiquette.
Atome 5 : La Collection Magique (La Synthèse)
Objectif : Utiliser une liste pour traiter tout le monde uniformément.
List<Vehicule> garage = new List<Vehicule>();
garage.Add(new Voiture(...));
garage.Add(new Camion(...));
foreach (Vehicule v in garage)
{
// Chaque véhicule réagit selon sa propre nature (son override)
v.Klaxonner();
}
Résumé des outils de base
| Mot-clé | Rôle atomique |
|---|---|
: |
Établir le lien "Est un". |
virtual |
Donner la permission de changer. |
override |
Changer le comportement. |
base |
Envoyer une donnée au constructeur du dessus. |
Note : Pour les concepts comme le protected ou le sealed, consultez la page Concepts Intermédiaires.