CodeGym /Cours /C# SELF /Syntaxe de l'héritage et bas...

Syntaxe de l'héritage et base en C#

C# SELF
Niveau 20 , Leçon 1
Disponible

1. Introduction

Dans cette leçon, on va voir comment fonctionne la syntaxe de l'héritage en C# : on va apprendre à déclarer des classes dérivées, comprendre ce que c'est que le mot-clé base, et comment s'en servir pour accéder à la classe parente. Ça va pas seulement te simplifier la vie quand tu codes, mais ça rendra aussi ton programme bien plus élégant (et parfois, ça t'évitera de corriger des bugs de copier-coller à 3h du mat').

Voilà un exemple simple de la vraie vie : on a une classe Vehicle (véhicule) — c'est le plan de base, universel. Tous les véhicules peuvent rouler, ils ont une couleur, un constructeur, etc. :

public class Vehicle
{
    public string Brand { get; set; }
    public string Color { get; set; }

    public void Drive()
    {
        Console.WriteLine("On y va !");
    }
}
Classe de base Vehicle

Et maintenant, on veut ajouter un nouveau type de transport — une voiture. Une voiture, c'est toujours un véhicule, mais avec ses propres particularités (genre, le nombre de portes). Ce serait bizarre de tout réécrire sur la couleur et le constructeur, vu que c'est déjà défini !

L'héritage nous permet de dire : "Une voiture, c'est un véhicule, mais avec plein de petits trucs en plus."

2. Comment déclarer une classe fille

En C#, pour créer une classe héritée, on utilise les deux-points :. Après le nom de la classe, on indique de quelle classe on hérite.


public class Car : Vehicle
{
    public int NumberOfDoors { get; set; }
}
Déclaration de la classe héritée Car

Lis-le comme ça : la classe Car hérite tous les champs et méthodes de la classe Vehicle et y ajoute ses propres trucs — genre, le nombre de portes.

À noter : en C#, il n'y a que l'héritage simple des classes (c'est-à-dire qu'une classe ne peut hériter que d'UNE seule classe parente). Mais pour les interfaces — autant que tu veux ! (on en parlera plus tard).

Comment ça marche ?

Quand tu déclares :

Car myCar = new Car();

...ton objet myCar a accès à tous les champs/méthodes de Vehicle, et aussi à ses propres propriétés. Exemple :

myCar.Brand = "Toyota";
myCar.Color = "Bleu";
myCar.NumberOfDoors = 4;
myCar.Drive(); // Méthode héritée

Scénario réel :
Dans notre appli "en développement", on pourrait faire un menu des véhicules où l'utilisateur choisit le type de transport, et le programme affiche toutes ses propriétés. Quand tu ajoutes un nouveau type de véhicule, tu écris un minimum de code !

3. Héritage des constructeurs

Quand on crée des objets de classe dérivée, parfois on veut initialiser les propriétés de la classe de base via le constructeur. Genre, pour être sûr de pas oublier la marque et la couleur :


public class Vehicle
{
    public string Brand { get; set; }
    public string Color { get; set; }

    public Vehicle(string brand, string color)
    {
        Brand = brand;
        Color = color;
    }
}

Maintenant, dans le constructeur de la classe héritée, tu peux (et tu dois) appeler le constructeur de la classe de base ! Pour ça, on utilise le mot-clé base :


public class Car : Vehicle
{
    public int NumberOfDoors { get; set; }

    public Car(string brand, string color, int numberOfDoors)
        : base(brand, color) // on appelle le constructeur de Vehicle !
    {
        NumberOfDoors = numberOfDoors;
    }
}

À quoi ça ressemble en vrai ?

Car bmw = new Car("BMW", "Noir", 4);
Console.WriteLine($"{bmw.Brand}, {bmw.Color}, portes : {bmw.NumberOfDoors}");
bmw.Drive(); // Ça marche toujours !

Du coup, bmw — c'est à la fois une voiture et un véhicule. Il se souvient de ses "parents".

4. Différence entre base et this

En C#, il y a deux mots-clés pour bosser avec les membres de la classe : this et base.

  • this — pour accéder à l'objet courant (genre, son propre champ ou méthode).
  • basepour accéder à un membre de la classe de base (donc au parent).

Quand utiliser base ? Imagine que tu veux étendre la logique d'une méthode de la classe de base, ou juste initialiser la classe de base depuis la dérivée. Par exemple :


public class Bicycle : Vehicle
{
    public int NumberOfGears { get; set; }

    public Bicycle(string brand, string color, int gears)
        : base(brand, color)    // on appelle le constructeur de la classe de base
    {
        NumberOfGears = gears;
    }

    public void ShowInfo()
    {
        // On utilise les propriétés de la classe de base !
        Console.WriteLine($"{Brand} ({Color}), vitesses : {NumberOfGears}");
    }
}

5. Le mot-clé base dans les méthodes

base — ce n'est pas que pour les constructeurs ! Parfois tu veux changer le comportement d'une méthode de la classe de base, mais quand même utiliser une partie de sa logique.

Imaginons qu'on veut que la méthode Drive dans la classe Car affiche aussi quelle voiture on conduit :


public class Car : Vehicle
{
    public int NumberOfDoors { get; set; }

    public Car(string brand, string color, int numberOfDoors) 
        : base(brand, color)
    {
        NumberOfDoors = numberOfDoors;
    }

    public void DriveCar()
    {
        base.Drive(); // on appelle l'implémentation de base
        Console.WriteLine($"On conduit {Brand} avec {NumberOfDoors} portes !");
    }
}

Explication :
L'appel base.Drive(); — c'est comme dire : "Papa, raconte d'abord ta partie de l'histoire, et moi j'ajoute des détails !". Du coup, quand tu appelles DriveCar(), ça affiche :

On y va !
On conduit BMW avec 4 portes !

On parlera de la redéfinition des méthodes (override) dans les prochaines leçons :P

6. Schéma d'héritage

Visualisons un peu les relations entre les classes. Voilà un schéma simple (parce que le UML, c'est flippant, surtout le matin !) :

Vehicle (base)
   /         \
Car      Bicycle
  • Toutes les flèches vont de la classe dérivée VERS la classe de base.
  • Toutes les classes filles ont accès aux membres public/protected de la classe de base.

Différences entre public, protected et private

Petit rappel pour pas se mélanger.
Dans une classe dérivée, on voit :

Modificateur Visibilité dans la classe fille
public Oui
protected Oui
private Non

Erreur fréquente :
Essayer d'accéder à un champ private depuis la classe fille :


public class Vehicle
{
    private string secret = "Personne ne saura jamais !";
}

public class Car : Vehicle
{
    public void RevealSecret()
    {
        Console.WriteLine(secret); // Erreur ! Pas visible.
    }
}
private — c'est que pour la classe de base, pas de secrets de famille !

Comparaison : classe de base vs. classe dérivée

Vehicle Car (héritée)
Brand présent hérite
Color présent hérite
Drive() présent hérite (ou étend)
NumberOfDoors non propre (propriété unique)

7. Exemple

Si on continue à développer une appli simple "Gestion des véhicules", on peut la construire comme ça :


public class Vehicle
{
    public string Brand { get; set; }
    public string Color { get; set; }

    public Vehicle(string brand, string color)
    {
        Brand = brand;
        Color = color;
    }

    public void Drive()
    {
        Console.WriteLine($"{Brand} {Color} est parti !");
    }
}

public class Car : Vehicle
{
    public int NumberOfDoors { get; set; }

    public Car(string brand, string color, int numberOfDoors)
        : base(brand, color)
    {
        NumberOfDoors = numberOfDoors;
    }

    public void ShowCar()
    {
        Console.WriteLine($"Marque : {Brand}, Couleur : {Color}, Portes : {NumberOfDoors}");
    }
}

public class Bicycle : Vehicle
{
    public int NumberOfGears { get; set; }

    public Bicycle(string brand, string color, int numberOfGears)
        : base(brand, color)
    {
        NumberOfGears = numberOfGears;
    }
}

Dans la méthode principale, tu peux créer une liste de véhicules et les décrire de différentes façons :

Car ford = new Car("Ford", "Rouge", 4);
ford.ShowCar();
ford.Drive();

Bicycle trek = new Bicycle("Trek", "Vert", 21);
trek.Drive();

8. Erreurs, particularités, et un peu d'humour

Erreur super fréquente — oublier d'appeler le constructeur de base dans la classe fille. Si Vehicle n'a pas de constructeur sans paramètres, et que t'as pas appelé base(...), tu vas avoir une erreur de compilation : le compilateur va râler qu'il ne peut pas initialiser la base. C'est comme essayer de construire le deuxième étage sans le premier. Ça marche pas. Faut passer les infos à l'étage du dessus.

Deuxième erreur : oublier que les champs/méthodes de la classe de base déclarés avec le modificateur private ne sont PAS VISIBLES dans les classes filles. Si tu veux laisser un truc pour les "enfants", utilise protected (on verra ça plus en détail dans les prochaines leçons).

Et surtout : l'héritage, c'est pratique, mais évite de faire des hiérarchies trop tordues. Dans la vraie vie, si ta chaîne d'héritage fait plus de deux-trois niveaux, y'a sûrement un souci. On se perd vite à savoir qui hérite de qui, et pourquoi on a fait tout ça.

2
Mission
C# SELF, niveau 20, leçon 1
Bloqué
Héritage avec utilisation du constructeur de la classe de base
Héritage avec utilisation du constructeur de la classe de base
2
Mission
C# SELF, niveau 20, leçon 1
Bloqué
Utilisation du mot-clé `base` pour appeler une méthode de la classe de base
Utilisation du mot-clé `base` pour appeler une méthode de la classe de base
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION