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 avez souvent besoin de effectuer des conversions entre les types de base et les types dérivés. L'upcasting convertit un type dérivé en son type de base, tandis que le downcasting fait l'inverse.

L'upcasting est implicite et toujours sûr car une classe dérivée est garantie de posséder tout ce que la classe de base possède :

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

Le downcasting nécessite un transtypage explicite et peut échouer à l'exécution si l'objet n'est pas réellement du type vers lequel vous effectuez le transtypage :

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 downcast 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 pattern matching is est privilégiée en C# moderne car elle combine la vérification de type et le transtypage en une seule étape, rendant votre code à la fois plus sûr et plus propre.

challenge icon

Défi

Facile

Construisons un système d'inspection de véhicules qui dé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 allez créer différents types de véhicules et écrire du code qui identifie et interagit en toute sécurité avec 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 via un constructeur. Incluez une méthode appelée GetBasicInfo() qui retourne "Vehicle: {LicensePlate}".
  • Car.cs : Définissez une classe Car dans l'espace de noms Inspection qui hérite de Vehicle. Les voitures ont 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 retourne "{LicensePlate} honks: Beep beep!".
  • Motorcycle.cs : Définissez une classe Motorcycle dans l'espace de noms Inspection qui hérite de Vehicle. Les motos ont une propriété HasSidecar (bool). Le constructeur accepte la plaque d'immatriculation et le statut du side-car. Ajoutez une méthode appelée Rev() qui retourne "{LicensePlate} revs: Vroom!".
  • Program.cs : Dans votre fichier principal, vous créerez des véhicules et pratiquerez à la fois l'upcasting et le downcasting sécurisé. Créez une Car et une Motorcycle en utilisant les valeurs d'entrée, puis stockez 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 le filtrage par motif (pattern matching) 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
  • Possède 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 devrait être :

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

Remarquez comment tous les véhicules sont stockés en tant que références Vehicle (upcasting), mais vous pouvez découvrir en toute sécurité leurs types réels et accéder aux méthodes spécifiques au type en utilisant la syntaxe de pattern matching is pour le downcasting !

Aide-mémoire

Lorsque vous travaillez avec des hiérarchies d'héritage, l'upcasting convertit un type dérivé en son type de base, tandis que le downcasting convertit un type de base en un type dérivé.

L'upcasting est implicite et toujours sûr :

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

Le downcasting nécessite un transtypage explicite et peut échouer à l'exécution :

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 exception InvalidCastException !

Downcasting sécurisé en utilisant le mot-clé is avec le filtrage par motif (préféré) :

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

Downcasting sécurisé en utilisant le mot-clé as (retourne null si le transtypage échoue) :

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

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