C# polymorphisme

Le polymorphisme est la capacité d'un même comportement à avoir plusieurs formes ou manifestations différentes.

polymorphismeIl signifie avoir plusieurs formes. Dans le paradigme de la programmation orientée objet, le polymorphisme se manifeste souvent par « une interface, plusieurs fonctions ».

Le polymorphisme peut être statique ou dynamique. Dansle polymorphisme statiquece cas, la réponse d'une fonction se produit au moment de la compilation. Dansle polymorphisme dynamiqueoù la réponse de la fonction se produit à l'exécution.

En C#, chaque type est polymorphe car tous les types, y compris les types définis par l'utilisateur, héritent d'Object.

Le polymorphisme signifie la même interface, utilisant différentes instances pour effectuer différentes opérations, comme le montre la figure :

Dans la vie réelle, par exemple, l'action d'appuyer sur la touche F1 :

  • Si actuellement dans l'interface Flash, le pop-up est le document d'aide AS 3 ;
  • Si actuellement dans Word, le pop-up est l'aide Word ;
  • Si sous Windows, le pop-up est Aide et support Windows.

Le même événement se produisant sur différents objets produira des résultats différents.

Polymorphisme statique

Au moment de la compilation, le mécanisme qui relie les fonctions et les objets est appelé liaison précoce, également appelée liaison statique. C# fournit deux techniques pour implémenter le polymorphisme statique. Ce sont :

  • Surcharge de fonctions
  • Surcharge des opérateurs

La surcharge d'opérateurs sera abordée dans le chapitre suivant ; ensuite, nous aborderons la surcharge de fonctions.


Surcharge de fonctions

Vous pouvez avoir plusieurs définitions du même nom de fonction dans la même portée. Les définitions de la fonction doivent différer les unes des autres, soit par les types des paramètres dans la liste des paramètres, soit par le nombre de paramètres. Les différentes surcharges ne sont pas des déclarations de fonction qui ne diffèrent que par le type de retour.

L'exemple suivant montre plusieurs fonctions identiquesAdd(), utilisées pour effectuer une addition sur différents nombres de paramètres :

Exemple

using System;
namespace PolymorphismApplication
{
    public class TestData  
    {  
        public int Add(int a, int b, int c)  
        {  
            return a + b + c;  
        }  
        public int Add(int a, int b)  
        {  
            return a + b;  
        }  
    }  
    class Program  
    {  
        static void Main(string[] args)  
        {  
            TestData dataClass = new TestData();
            int add1 = dataClass.Add(1, 2);  
            int add2 = dataClass.Add(1, 2, 3);

            Console.WriteLine("add1 :" + add1);
            Console.WriteLine("add2 :" + add2);  
        }  
    }  
}

L'exemple suivant montre plusieurs fonctions identiquesprint(), utilisées pour afficher différents types de données :

Exemple

using System;
namespace PolymorphismApplication
{
   class Printdata
   {
      void print(int i)
      {
         Console.WriteLine("Entier de sortie : {0}", i );
      }

      void print(double f)
      {
         Console.WriteLine("Type à virgule flottante de sortie : {0}" , f);
      }

      void print(string s)
      {
         Console.WriteLine("Chaîne de sortie : {0}", s);
      }
      static void Main(string[] args)
      {
         Printdata p = new Printdata();
         // Appeler print pour afficher l'entier
         p.print(1);
         // Appeler print pour afficher un nombre à virgule flottante
         p.print(1.23);
         // Appeler print pour afficher une chaîne de caractères
         p.print("Hello Example");
         Console.ReadKey();
      }
   }
}

Lorsque le code ci-dessus est compilé et exécuté, il produit les résultats suivants :

输出整型: 1
输出浮点型: 1.23
输出字符串: Hello Example

Polymorphisme dynamique

C# vous permet d'utiliser le mot-cléabstractpour créer une classe abstraite afin de fournir une implémentation partielle d'une interface. Lorsqu'une classe dérivée hérite de la classe abstraite, l'implémentation est complète.Classe abstraiteContient des méthodes abstraites, qui peuvent être implémentées par des classes dérivées. Les classes dérivées ont des fonctionnalités plus spécialisées.

Veuillez noter que les règles concernant les classes abstraites sont ci-dessous :

  • Vous ne pouvez pas créer une instance d'une classe abstraite.
  • Vous ne pouvez pas déclarer une méthode abstraite en dehors d'une classe abstraite.
  • En plaçant le mot-clésealedavant la définition de la classe, la classe peut être déclarée commesealed class. Lorsque la classe est déclarée commesealedLorsqu'elle est sealed, elle ne peut pas être héritée. Une classe abstraite ne peut pas être déclarée comme sealed.

Le programme suivant démontre une classe abstraite :

Exemple

using System;
namespace PolymorphismApplication
{
   abstract class Shape
   {
       abstract public int area();
   }
   class Rectangle:  Shape
   {
      private int length;
      private int width;
      public Rectangle( int a=0, int b=0)
      {
         longueur = a;
         width = b;
      }
      public override int area ()
      {
         Console.WriteLine(L'aire de la classe Rectangle :);
         return (width * length);
      }
   }

   class RectangleTester
   {
      static void Main(string[] args)
      {
         Rectangle r = new Rectangle(10, 7);
         double a = r.area();
         Console.WriteLine("Aire : {0}",a);
         Console.ReadKey();
      }
   }
}

Lorsque le code ci-dessus est compilé et exécuté, il produit les résultats suivants :

Rectangle 类的面积:
面积: 70

Lorsqu'il y a une fonction définie dans une classe qui doit être implémentée dans une classe héritée, vous pouvez utiliserune méthode virtuelle。

Une méthode virtuelle est déclarée à l'aide du mot-clévirtualDéclarée.

Les méthodes virtuelles peuvent avoir différentes implémentations dans différentes classes héritées.

L'appel à une méthode virtuelle se produit au moment de l'exécution.

Le polymorphisme dynamique est réalisé grâce àclasse abstraiteetméthode virtuelleImplémenté.

L'exemple suivant crée une classe de base Shape et des classes dérivées Circle, Rectangle, Triangle. La classe Shape fournit une méthode virtuelle nommée Draw, qui est redéfinie dans chaque classe dérivée pour dessiner la forme spécifiée pour cette classe.

Exemple

using System;
using System.Collections.Generic;

public class Shape
{
    public int X { get; private set; }
    public int Y { get; private set; }
    public int Height { get; set; }
    public int Width { get; set; }
   
    // Méthode virtuelle
    public virtual void Draw()
    {
        Console.WriteLine("Exécuter la tâche de dessin de la classe de base");
    }
}

class Circle : Shape
{
    public override void Draw()
    {
        Console.WriteLine("Dessiner un cercle");
        base.Draw();
    }
}
class Rectangle : Shape
{
    public override void Draw()
    {
        Console.WriteLine("Dessiner un rectangle");
        base.Draw();
    }
}
class Triangle : Shape
{
    public override void Draw()
    {
        Console.WriteLine("Dessiner un triangle");
        base.Draw();
    }
}

class Program
{
    static void Main(string[] args)
    {
        // Créez un objet List<Shape> et ajoutez-y Circle, Triangle et Rectangle.
        var shapes = new List<Shape>
        {
            new Rectangle(),
            new Triangle(),
            new Circle()
        };

        // Utilisez une boucle foreach pour parcourir les classes dérivées de cette liste, et appelez la méthode Draw sur chaque objet Shape
        foreach (var shape in shapes)
        {
            shape.Draw();
        }

        Console.WriteLine("Appuyez sur une touche pour quitter.");
        Console.ReadKey();
    }

}

Lorsque le code ci-dessus est compilé et exécuté, il produit les résultats suivants :

Draw a rectangle
Execute the base class drawing task
Draw a triangle
Execute the base class drawing task
Draw a circle
Execute the base class drawing task
Press any key to exit.

Le programme suivant montre comment calculer l'aire de différentes formes à l'aide de la méthode virtuelle area() :

Exemple

using System;
namespace PolymorphismApplication
{
   class Shape
   {
      protected int width, height;
      public Shape( int a=0, int b=0)
      {
         width = a;
         height = b;
      }
      public virtual int area()
      {
         Console.WriteLine("Aire de la classe parente :");
         return 0;
      }
   }
   class Rectangle: Shape
   {
      public Rectangle( int a=0, int b=0): base(a, b)
      {

      }
      public override int area ()
      {
         Console.WriteLine(L'aire de la classe Rectangle :);
         return (width * height);
      }
   }
   class Triangle: Shape
   {
      public Triangle(int a = 0, int b = 0): base(a, b)
      {
     
      }
      public override int area()
      {
         Console.WriteLine("Aire de la classe Triangle :");
         return (width * height / 2);
      }
   }
   class Caller
   {
      public void CallArea(Shape sh)
      {
         int a;
         a = sh.area();
         Console.WriteLine("Aire : {0}", a);
      }
   }  
   class Tester
   {
     
      static void Main(string[] args)
      {
         Caller c = new Caller();
         Rectangle r = new Rectangle(10, 7);
         Triangle t = new Triangle(10, 5);
         c.CallArea(r);
         c.CallArea(t);
         Console.ReadKey();
      }
   }
}

Lorsque le code ci-dessus est compilé et exécuté, il produit les résultats suivants :

Rectangle 类的面积:
面积:70
Triangle 类的面积:
面积:25
autres extensions