Le Polymorphisme en C# : Une Approche Orientée Objet

Le polymorphisme est un pilier fondamental de la programmation orientée objet, permettant à une méthode d'exister avec différentes implémentations sous un même nom. Dans une hiérarchie d'héritage, différentes classes dérivées d'une classe de base commune peuvent fournir leurs propres versions spécifiques d'une méthode héritée, conduisant à des comportements variés lorsqu'elle est appliquée à des objets de ces classes.

L'un des principaux avantages du polymorphisme réside dans la réutilisation de l'interface. En C#, le polymorphisme à l'exécution est principalement réalisé par l'utilisation et la redéfinition de méthodes dans les relations d'héritage entre les classes de base et dérivées.

Méthodes Virtuelles : La Clé du Polymorphisme

Lorsqu'une classe de base définit une méthode et que l'on souhaite permettre aux classes dérivées d'hériter de cette méthode tout en en modifiant l'implémentation, cette méthode doit être déclarée comme virtual dans la classe de base. Les classes dérivées peuvent ensuite la redéfinir en utilisant le mot-clé override pour implémenter le polymorphisme.

Important : Seules les méthodes virtuelles peuvent être redéfinies. Elles doivent être accessibles par les classes dérivées, donc leurs modificateurs d'accès ne peuvent pas être private ; ils peuvent être public ou protected. Les méthodes virtuelles doivent également être des méthodes d'instance (non statiques), car le polymorphisme s'opère au niveau des objets, tandis que les méthodes statiques opèrent au niveau des classes.

Dans la classe de base, le mot-clé virtual précède la déclaration de la méthode. Dans la classe dérivée, le mot-clé override est utilisé pour redéfinir la méthode virtuelle de la classe de base. Les noms de méthode, les types de retour, ainsi que le nombre et les types des paramètres doivent être identiques entre la méthode de la classe de base et sa redéfinition dans la classe dérivée.

public class Program
{
    public static void Main(string[] args)
    {
        // Instanciation directe de la classe de base
        BaseClass parentObj = new BaseClass();
        parentObj.DisplayMessage();

        // Instanciation de la classe dérivée
        DerivedClass childObj = new DerivedClass();
        childObj.DisplayMessage();

        // Instanciation d'un objet dérivé assigné à une référence de la classe de base
        BaseClass polymorphicObj = new DerivedClass();
        polymorphicObj.DisplayMessage(); // L'implémentation de la classe dérivée sera appelée

        Console.ReadKey();
    }
}

public class BaseClass
{
    public virtual void DisplayMessage()
    {
        Console.WriteLine("Message de la classe de base !");
    }
}

public class DerivedClass : BaseClass
{
    public override void DisplayMessage()
    {
        // Optionnel : appel de la méthode de la classe de base avant la redéfinition
        // base.DisplayMessage();
        Console.WriteLine("Message de la classe dérivée redéfini !");
    }
}

Il est possible d'appeler la méthode de la classe de base depuis une méthode redéfinie dans la classe dérivée en utilisant la syntaxe base.NomMethode(), à condition que cette méthode ne soit pas privée.

Illustration du Polymorphisme

public class Program
{
    // Méthode qui accepte une référence de la classe de base
    public static void ProcessObject(BaseClass obj)
    {
        obj.DisplayMessage(); // Appelle la méthode appropriée selon le type réel de l'objet
    }

    public static void Main(string[] args)
    {
        BaseClass baseInstance = new BaseClass();
        ProcessObject(baseInstance); // Appel avec un objet de la classe de base

        DerivedClass derivedInstance = new DerivedClass();
        ProcessObject(derivedInstance); // Appel avec un objet de la classe dérivée

        // On peut aussi passer un objet dérivé via une référence de base
        BaseClass polymorphicReference = new DerivedClass();
        ProcessObject(polymorphicReference);

        Console.ReadKey();
    }
}

public class BaseClass
{
    public virtual void DisplayMessage()
    {
        Console.WriteLine("Affichage depuis la classe de base.");
    }
}

public class DerivedClass : BaseClass
{
    public override void DisplayMessage()
    {
        Console.WriteLine("Affichage depuis la classe dérivée redéfinie.");
    }
}

Dans l'exemple ci-dessus, la méthode statique ProcessObject accepte un paramètre de type BaseClass. Lorsque l'on lui passe une instance de BaseClass ou une instance de DerivedClass, l'appel à obj.DisplayMessage() exécute l'implémentation correcte de la méthode en fonction du type réel de l'objet passé en argument. Cela démontre le polymorphisme et permet de concevoir une méthode (ici ProcessObject) qui peut fonctionner avec des objets de la classe de base et de toutes ses classes dérivées.

Polymorphisme vs. Surcharge (Overloading)

Bien que le polymorphisme et la surcharge impliquent tous deux des méthodes portant le même nom, leurs mécanismes et objectifs diffèrent fondamentalement.

La surcharge concerne la définition de plusieurs méthodes portant le même nom au sein d'une même classe. Ces méthodes doivent avoir des listes de paramètres distinctes (différent par le nombre ou le type de paramètres). Le compilateur détermine quelle méthode appeler en se basant sur les arguments fournis lors de l'appel. Le type de retour peut être identique ou différent.

Le polymorphisme, quant à lui, se manifeste dans une hiérarchie d'héritage. La redéfinition d'une méthode virtuelle dans une classe dérivée (avec override) permet d'obtenir un comportemant différent pour une même signature de méthode. La classe de base utilise virtual pour déclarer la méthode, et la classe dérivée utilise override pour la redéfinir. Les signatures (nom, type de retour, paramètres) doivent être identiques.

Étiquettes: C# polymorphisme Héritage méthode virtuelle Override

Publié le 28 septembre à 01h37