Menu
Coddy logo textTech

Upcasting & Downcasting

Fait partie de la section Programmation Orientée Objet du Journey C# de Coddy. Leçon 29 sur 70.

Lorsque vous travaillez avec des hiérarchies d’héritage, vous devez souvent convertir des types de base et des types dérivés. Le upcasting convertit un type dérivé en son type de base, tandis que le downcasting fait l’inverse.

La conversion vers une classe de base est implicite et toujours sûre, car il est garanti qu’une classe dérivée possède tout ce que possède la classe de base :

Dog myDog = new Dog();
Animal animal = myDog;  // Upcasting - implicite, fonctionne toujours

Le downcasting nécessite une conversion explicite et peut échouer lors de l’exécution si l’objet n’est pas réellement du type vers lequel vous effectuez la conversion :

Animal animal = new Dog();
Dog dog = (Dog)animal;  // Downcasting - fonctionne car c'est réellement un Dog

Animal cat = new Cat();
Dog wrong = (Dog)cat;   // Lève une InvalidCastException !

Pour effectuer un transtypage descendant en toute sécurité, utilisez le mot-clé is pour vérifier d’abord le type, ou utilisez as, qui renvoie null au lieu de lever une exception :

if (animal is Dog d)
{
    d.Bark();  // Sûr - d n'est disponible que si la vérification réussit
}

Dog maybeDog = animal as Dog;
if (maybeDog != null)
{
    maybeDog.Bark();
}

L’approche de correspondance de modèle is est privilégiée en C# moderne, car elle combine la vérification de type et la conversion en une seule étape, ce qui rend votre code à la fois plus sûr et plus clair.

challenge icon

Défi

Facile

Construisons un système d’inspection de véhicules qui montre comment l’upcasting et le downcasting vous permettent de travailler de manière flexible avec des objets dans une hiérarchie d’héritage. Vous créerez différents types de véhicules et écrirez du code qui identifie et utilise en toute sécurité des types de véhicules spécifiques.

Vous organiserez votre code sur quatre fichiers :

  • Vehicle.cs : définissez une classe de base Vehicle dans l’espace de noms Inspection. Chaque véhicule possède une propriété LicensePlate (string) définie par l’intermédiaire d’un constructeur. Incluez une méthode appelée GetBasicInfo() qui renvoie "Vehicle: {LicensePlate}".
  • Car.cs : définissez une classe Car dans l’espace de noms Inspection qui hérite de Vehicle. Les voitures possèdent une propriété supplémentaire NumberOfDoors (int). Le constructeur accepte à la fois la plaque d’immatriculation et le nombre de portes. Ajoutez une méthode appelée Honk() qui renvoie "{LicensePlate} honks: Beep beep!".
  • Motorcycle.cs : définissez une classe Motorcycle dans l’espace de noms Inspection qui hérite de Vehicle. Les motos possèdent une propriété HasSidecar (bool). Le constructeur accepte la plaque d’immatriculation et la présence ou non d’un side-car. Ajoutez une méthode appelée Rev() qui renvoie "{LicensePlate} revs: Vroom!".
  • Program.cs : dans votre fichier principal, vous créerez des véhicules et vous vous exercerez à la fois à l’upcasting et au downcasting sécurisé. Créez une Car et une Motorcycle à l’aide de valeurs saisies, puis stockez-les toutes les deux dans un tableau de références Vehicle (upcasting). Parcourez le tableau et, pour chaque véhicule, affichez ses informations de base. Utilisez ensuite le mot-clé is avec la reconnaissance de formes pour effectuer un downcasting sécurisé : s’il s’agit d’une Car, appelez Honk() ; s’il s’agit d’une Motorcycle, appelez Rev().

Vous recevrez quatre entrées :

  • Plaque d’immatriculation de la voiture
  • Nombre de portes
  • Plaque d’immatriculation de la moto
  • Présence d’un side-car (true ou false)

Affichez la sortie dans ce format pour chaque véhicule du tableau :

{GetBasicInfo() result}
{Honk() or Rev() result based on actual type}

Par exemple, si les entrées sont ABC-123, 4, XYZ-789 et false, la sortie doit être :

Vehicle: ABC-123
ABC-123 honks: Beep beep!
Vehicle: XYZ-789
XYZ-789 revs: Vroom!

Remarquez que tous les véhicules sont stockés en tant que références Vehicle (upcasting), mais que vous pouvez découvrir en toute sécurité leurs véritables types et accéder à des méthodes spécifiques à leur type en utilisant la syntaxe de reconnaissance de formes is pour effectuer un downcasting !

Essayez vous-même

using System;
using Inspection;

class Program
{
    public static void Main(string[] args)
    {
        // Lire les entrées
        string carPlate = Console.ReadLine();
        int numberOfDoors = Convert.ToInt32(Console.ReadLine());
        string motorcyclePlate = Console.ReadLine();
        bool hasSidecar = Convert.ToBoolean(Console.ReadLine());
        
        // TODO: Créer un objet Car en utilisant carPlate et numberOfDoors
        
        // TODO: Créer un objet Motorcycle en utilisant motorcyclePlate et hasSidecar
        
        // TODO: Créer un tableau de références Vehicle contenant les deux véhicules (upcasting)
        
        // TODO: Parcourir le tableau et pour chaque véhicule :
        //   - Afficher le résultat de GetBasicInfo()
        //   - Utiliser le mot-clé 'is' avec le pattern matching pour effectuer un downcast sécurisé :
        //     - Si c'est une Car, appeler et afficher Honk()
        //     - Si c'est une Motorcycle, appeler et afficher Rev()
    }
}
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Programmation Orientée Objet

Entraînez-vous par vous-même : Compilateur C# en ligne