Menu
Coddy logo textTech

Mots-clés Virtual & Override

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

Lorsqu'une classe dérivée hérite d'une méthode, vous souhaitez parfois modifier complètement le comportement de cette méthode. Les mots-clés virtual et override travaillent ensemble pour rendre cela possible de manière contrôlée.

Marquez une méthode comme virtual dans la classe de base pour signaler que les classes dérivées sont autorisées à remplacer son implémentation :

public class Animal
{
    public virtual void Speak()
    {
        Console.WriteLine("Some sound");
    }
}

public class Dog : Animal
{
    public override void Speak()
    {
        Console.WriteLine("Woof!");
    }
}

Le mot-clé override dans la classe dérivée indique au compilateur que vous remplacez intentionnellement la méthode de base. Sans virtual sur la méthode de base, vous ne pouvez pas utiliser override.

La véritable puissance se manifeste lorsque vous utilisez une référence de classe de base pour contenir un objet dérivé :

Animal myPet = new Dog();
myPet.Speak();  // Sortie : Woof!

Même si myPet est déclaré comme Animal, C# appelle la version Dog de Speak(). C'est ce qu'on appelle le polymorphisme d'exécution : la méthode réellement appelée dépend du type réel de l'objet, et non du type déclaré de la variable.

Vous pouvez toujours accéder à l'implémentation de base en utilisant base.Speak() à l'intérieur de votre redéfinition si vous souhaitez étendre plutôt que de remplacer complètement le comportement.

challenge icon

Défi

Facile

Construisons un système de notification qui démontre comment les classes dérivées peuvent remplacer complètement le comportement de la classe de base en utilisant les mots-clés virtual et override, tout en montrant la puissance du polymorphisme au moment de l'exécution.

Vous allez créer trois fichiers pour organiser votre code :

  • Notification.cs : Définissez une classe Notification dans l'espace de noms Alerts. Cette classe de base représente une notification générique avec une propriété Message (string) et un constructeur qui l'initialise. Incluez une méthode virtual nommée Send() qui retourne "Sending notification: {Message}".
  • EmailNotification.cs : Définissez une classe EmailNotification dans l'espace de noms Alerts qui hérite de Notification. Ajoutez une propriété Recipient (string) et un constructeur qui accepte à la fois le message et le destinataire (utilisez base pour transmettre le message). Surchargez la méthode Send() pour retourner "Emailing {Recipient}: {Message}".
  • SmsNotification.cs : Définissez une classe SmsNotification dans l'espace de noms Alerts qui hérite également de Notification. Ajoutez une propriété PhoneNumber (string) et un constructeur qui accepte à la fois le message et le numéro de téléphone. Surchargez Send() pour retourner "SMS to {PhoneNumber}: {Message}".
  • Program.cs : Dans votre fichier principal, créez des instances des trois types de notification en utilisant les valeurs d'entrée. Démontrez ensuite le polymorphisme au moment de l'exécution en stockant les trois instances dans des variables de type Notification et en appelant Send() sur chacune d'elles.

Vous recevrez quatre entrées :

  • Le message de notification
  • L'adresse e-mail du destinataire
  • Le numéro de téléphone pour le SMS

Affichez le résultat de l'appel à Send() sur chaque notification, stockée en tant que référence de la classe de base :

{base notification Send() result}
{email notification Send() result}
{sms notification Send() result}

Par exemple, si les entrées sont Meeting at 3pm, alice@email.com, et 555-1234, la sortie devrait être :

Sending notification: Meeting at 3pm
Emailing alice@email.com: Meeting at 3pm
SMS to 555-1234: Meeting at 3pm

Remarquez comment, même si les trois sont stockées dans des variables de type Notification, chacune appelle sa propre version surchargée de Send(). C'est le polymorphisme au moment de l'exécution en action !

Aide-mémoire

Utilisez le mot-clé virtual dans une classe de base pour marquer une méthode que les classes dérivées peuvent remplacer :

public class Animal
{
    public virtual void Speak()
    {
        Console.WriteLine("Some sound");
    }
}

Utilisez le mot-clé override dans une classe dérivée pour remplacer l'implémentation de la méthode de la classe de base :

public class Dog : Animal
{
    public override void Speak()
    {
        Console.WriteLine("Woof!");
    }
}

Le polymorphisme à l'exécution se produit lorsqu'une référence de classe de base contient un objet dérivé - la méthode réellement appelée dépend du type réel de l'objet, et non du type déclaré de la variable :

Animal myPet = new Dog();
myPet.Speak();  // Sortie : Woof!

Vous pouvez accéder à l'implémentation de base à l'intérieur d'une substitution en utilisant base :

public override void Speak()
{
    base.Speak();  // Appelle la version de la classe de base
    Console.WriteLine("Woof!");
}

Essayez vous-même

using System;
using Alerts;

class Program
{
    public static void Main(string[] args)
    {
        // Lire les entrées
        string message = Console.ReadLine();
        string email = Console.ReadLine();
        string phone = Console.ReadLine();

        // TODO: Créer des instances des trois types de notification
        // Les stocker dans des variables Notification pour démontrer le polymorphisme
        
        // TODO: Créer une Notification de base
        Notification baseNotification;
        
        // TODO: Créer une EmailNotification (stockée en tant que type Notification)
        Notification emailNotification;
        
        // TODO: Créer une SmsNotification (stockée en tant que type Notification)
        Notification smsNotification;
        
        // TODO: Appeler Send() sur chacune et afficher les résultats
        // Les méthodes redéfinies seront appelées grâce au polymorphisme à l'exécution
    }
}
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