Menu
Coddy logo textTech

Polymorphisme : Compilation vs Exécution

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

Le polymorphisme signifie « plusieurs formes » - la capacité pour le même code de se comporter différemment selon le contexte. C# prend en charge deux types distincts de polymorphisme, et comprendre quand chacun est résolu vous aide à écrire du code plus flexible.

Le polymorphisme à la compilation (également appelé polymorphisme statique) est résolu par le compilateur avant l'exécution de votre programme. La surcharge de méthodes en est le principal exemple : plusieurs méthodes partagent le même nom mais ont des paramètres différents :

public class Calculator
{
    public int Add(int a, int b) => a + b;
    public double Add(double a, double b) => a + b;
}

var calc = new Calculator();
calc.Add(5, 3);       // Le compilateur choisit la version int
calc.Add(5.0, 3.0);   // Le compilateur choisit la version double

Le compilateur examine les types d'arguments et sélectionne la méthode correcte au moment de la compilation. Cette décision est fixée avant même que le programme ne s'exécute.

Le polymorphisme d'exécution (polymorphisme dynamique) est résolu pendant l'exécution du programme. Cela se produit avec les méthodes virtual et override - le type réel de l'objet détermine quelle méthode est exécutée :

Animal pet = new Dog();  // Déclaré comme Animal, en réalité un Dog
pet.Speak();             // Appelle le Speak() de Dog à l'exécution

Le compilateur ne sait pas quel Speak() s'exécutera - cette décision se prend à l'exécution en fonction du type réel de l'objet. C'est ce qui rend le polymorphisme basé sur l'héritage si puissant pour construire des systèmes flexibles et extensibles.

challenge icon

Défi

Facile

Construisons un système de conversion qui illustre les deux types de polymorphisme en action. Vous allez créer une classe qui utilise la surcharge de méthodes (polymorphisme au moment de la compilation) ainsi qu'une hiérarchie d'héritage qui utilise des méthodes virtuelles/redéfinies (polymorphisme au moment de l'exécution).

Vous organiserez votre code sur quatre fichiers :

  • Converter.cs : Définissez une classe Converter dans l'espace de noms Conversion. Cette classe illustre le polymorphisme au moment de la compilation par la surcharge de méthodes. Créez trois méthodes Convert surchargées :
    • Convert(int value) retourne "Integer: {value}"
    • Convert(double value) retourne "Double: {value}"
    • Convert(string value) retourne "String: {value}"
  • Shape.cs : Définissez une classe de base Shape dans l'espace de noms Conversion. Cette classe possède une propriété Name (string) et un constructeur qui la définit. Incluez une méthode virtual appelée Describe() qui retourne "This is a {Name}".
  • Circle.cs : Définissez une classe Circle dans l'espace de noms Conversion qui hérite de Shape. Ajoutez une propriété Radius (double). Le constructeur accepte un rayon et passe "Circle" au constructeur de base. Redéfinissez (override) Describe() pour retourner "This is a Circle with radius {Radius}".
  • Program.cs : Dans votre fichier principal, illustrez les deux types de polymorphisme. Tout d'abord, créez un Converter et appelez les trois méthodes surchargées avec les valeurs d'entrée. Ensuite, créez un Circle, stockez-le dans une variable Shape, et appelez Describe() pour montrer le polymorphisme au moment de l'exécution.

Vous recevrez quatre entrées :

  • Une valeur entière (int)
  • Une valeur décimale (double)
  • Une valeur textuelle (string)
  • Un rayon de cercle (double)

Affichez la sortie dans ce format :

Compile-time Polymorphism:
{Convert(int) result}
{Convert(double) result}
{Convert(string) result}
Runtime Polymorphism:
{Describe() result from Shape variable holding Circle}

Par exemple, si les entrées sont 42, 3.14, Hello, et 5.5, la sortie devrait être :

Compile-time Polymorphism:
Integer: 42
Double: 3.14
String: Hello
Runtime Polymorphism:
This is a Circle with radius 5.5

Remarquez la différence clé : le compilateur décide quelle méthode Convert appeler en fonction des types d'arguments au moment de la compilation, tandis que la méthode Describe() est résolue au moment de l'exécution en fonction du type réel de l'objet, même s'il est stocké dans une variable Shape !

Aide-mémoire

Le polymorphisme signifie « plusieurs formes » - la capacité pour le même code de se comporter différemment selon le contexte.

Le polymorphisme à la compilation (polymorphisme statique) est résolu par le compilateur avant l'exécution du programme. La surcharge de méthode en est le principal exemple :

public class Calculator
{
    public int Add(int a, int b) => a + b;
    public double Add(double a, double b) => a + b;
}

var calc = new Calculator();
calc.Add(5, 3);       // Le compilateur choisit la version int
calc.Add(5.0, 3.0);   // Le compilateur choisit la version double

Le compilateur examine les types d'arguments et sélectionne la méthode correcte au moment de la compilation.

Le polymorphisme à l'exécution (polymorphisme dynamique) est résolu pendant l'exécution du programme à l'aide des méthodes virtual et override :

Animal pet = new Dog();  // Déclaré comme Animal, est en réalité un Dog
pet.Speak();             // Appelle Speak() de Dog à l'exécution

Le type réel de l'objet détermine quelle méthode s'exécute au moment de l'exécution, et non le type de variable déclaré.

Essayez vous-même

using System;
using Conversion;

class Program
{
    public static void Main(string[] args)
    {
        // Lire les entrées
        int intValue = Convert.ToInt32(Console.ReadLine());
        double doubleValue = Convert.ToDouble(Console.ReadLine());
        string stringValue = Console.ReadLine();
        double radius = Convert.ToDouble(Console.ReadLine());

        // TODO: Démontrer le polymorphisme à la compilation (Compile-time Polymorphism)
        // Créer un objet Converter et appeler les trois méthodes Convert surchargées
        Console.WriteLine("Compile-time Polymorphism:");
        // Appeler Convert avec intValue, doubleValue, et stringValue

        // TODO: Démontrer le polymorphisme au moment de l'exécution (Runtime Polymorphism)
        // Créer un objet Circle et le stocker dans une variable Shape
        // Ensuite, appeler Describe() sur la variable Shape
        Console.WriteLine("Runtime Polymorphism:");
        // Créer Circle et appeler Describe()
    }
}
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