C# Polymorphismus

Polymorphismus ist die Fähigkeit, dass dasselbe Verhalten mehrere verschiedene Formen oder Erscheinungsformen annehmen kann.

PolymorphismusEr bedeutet, mehrere Formen zu haben. Im Paradigma der objektorientierten Programmierung zeigt sich Polymorphismus oft als "eine Schnittstelle, mehrere Funktionen."

Polymorphismus kann statisch oder dynamisch sein. Beistatischem Polymorphismuserfolgt in diesem Fall die Reaktion einer Funktion zur Kompilierungszeit. Beidynamischem Polymorphismuserfolgt die Reaktion der Funktion zur Laufzeit.

In C# ist jeder Typ polymorph, weil alle Typen, einschließlich benutzerdefinierter Typen, von Object erben.

Polymorphismus bedeutet, dass dieselbe Schnittstelle mit unterschiedlichen Instanzen unterschiedliche Operationen ausführt, wie in der Abbildung gezeigt:

Im wirklichen Leben zum Beispiel die Aktion des Drückens der F1-Taste:

  • Wenn Sie sich derzeit in der Flash-Oberfläche befinden, ist das Pop-up das AS 3-Hilfedokument;
  • Wenn Sie sich derzeit in Word befinden, ist das Pop-up die Word-Hilfe;
  • Wenn Sie sich unter Windows befinden, ist das Pop-up Windows-Hilfe und Support.

Das gleiche Ereignis, das bei verschiedenen Objekten auftritt, führt zu unterschiedlichen Ergebnissen.

Statische Polymorphie

Zur Kompilierungszeit wird der Mechanismus, der Funktionen und Objekte verbindet, als frühe Bindung bezeichnet, auch als statische Bindung bekannt. C# bietet zwei Techniken zur Implementierung statischer Polymorphie. Sie sind:

  • Funktionsüberladung
  • Operatorüberladung

Operatorüberladung wird im nächsten Kapitel behandelt; als Nächstes besprechen wir die Funktionsüberladung.


Funktionsüberladung

Sie können mehrere Definitionen desselben Funktionsnamens im selben Gültigkeitsbereich haben. Die Definitionen der Funktion müssen sich voneinander unterscheiden, entweder in den Typen der Parameter in der Parameterliste oder in der Anzahl der Parameter. Unterschiedliche Überladungen sind keine Funktionsdeklarationen, die sich nur im Rückgabetyp unterscheiden.

Das folgende Beispiel veranschaulicht mehrere identische FunktionenAdd(), die verwendet werden, um Additionen mit unterschiedlicher Parameteranzahl durchzuführen:

Beispiel

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);  
        }  
    }  
}

Das folgende Beispiel demonstriert mehrere identische Funktionenprint(), die verwendet werden, um verschiedene Datentypen auszugeben:

Beispiel

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

      void print(double f)
      {
         Console.WriteLine("Gleitkommazahl ausgeben: {0}" , f);
      }

      void print(string s)
      {
         Console.WriteLine("Zeichenkette ausgeben: {0}", s);
      }
      static void Main(string[] args)
      {
         Printdata p = new Printdata();
         // print aufrufen, um die Ganzzahl auszugeben
         p.print(1);
         // print aufrufen, um eine Gleitkommazahl auszugeben
         p.print(1.23);
         // print aufrufen, um eine Zeichenkette auszugeben
         p.print("Hello Example");
         Console.ReadKey();
      }
   }
}

Wenn der obige Code kompiliert und ausgeführt wird, liefert er die folgenden Ergebnisse:

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

Dynamische Polymorphie

C# ermöglicht es Ihnen, das Schlüsselwortabstractzu verwenden. Erstellen Sie eine abstrakte Klasse, um eine partielle Implementierung einer Schnittstelle bereitzustellen. Wenn eine abgeleitete Klasse von der abstrakten Klasse erbt, ist die Implementierung vollständig.Abstrakte KlasseEnthält abstrakte Methoden, die von abgeleiteten Klassen implementiert werden können. Abgeleitete Klassen haben spezialisiertere Funktionalität.

Bitte beachten Sie: Nachfolgend sind einige Regeln zu abstrakten Klassen aufgeführt:

  • Sie können keine Instanz einer abstrakten Klasse erstellen.
  • Sie können eine abstrakte Methode nicht außerhalb einer abstrakten Klasse deklarieren.
  • Durch Platzieren des Schlüsselworts vor die Klassendefinitionsealedkann die Klasse alssealed classdeklariert werden. Wenn eine Klasse alssealed deklariert wirdWenn sealed, kann sie nicht vererbt werden. Eine abstrakte Klasse kann nicht als sealed deklariert werden.

Das folgende Programm demonstriert eine abstrakte Klasse:

Beispiel

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)
      {
         length = a;
         width = b;
      }
      public override int area ()
      {
         Console.WriteLine(Die Fläche der Klasse Rectangle:);
         return (width * length);
      }
   }

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

Wenn der obige Code kompiliert und ausgeführt wird, liefert er die folgenden Ergebnisse:

Rectangle 类的面积:
面积: 70

Wenn eine Funktion in einer Klasse definiert ist, die in einer abgeleiteten Klasse implementiert werden muss, kann man einevirtuelle Methode verwenden。

Eine virtuelle Methode wird mit dem Schlüsselwortvirtualdeklariert.

Virtuelle Methoden können unterschiedliche Implementierungen in verschiedenen abgeleiteten Klassen haben.

Der Aufruf einer virtuellen Methode erfolgt zur Laufzeit.

Dynamischer Polymorphismus wird durchabstrakte Klasseundvirtuelle Methodeimplementiert.

Das folgende Beispiel erstellt eine Basisklasse Shape und die abgeleiteten Klassen Circle, Rectangle, Triangle. Die Klasse Shape stellt eine virtuelle Methode namens Draw bereit, die in jeder abgeleiteten Klasse überschrieben wird, um die für diese Klasse angegebene Form zu zeichnen.

Beispiel

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; }
   
    // Virtuelle Methode
    public virtual void Draw()
    {
        Console.WriteLine("Führe die Zeichenaufgabe der Basisklasse aus");
    }
}

class Circle : Shape
{
    public override void Draw()
    {
        Console.WriteLine("Zeichne einen Kreis");
        base.Draw();
    }
}
class Rectangle : Shape
{
    public override void Draw()
    {
        Console.WriteLine("Zeichne ein Rechteck");
        base.Draw();
    }
}
class Triangle : Shape
{
    public override void Draw()
    {
        Console.WriteLine("Zeichne ein Dreieck");
        base.Draw();
    }
}

class Program
{
    static void Main(string[] args)
    {
        // Erstellen Sie ein List<Shape>-Objekt und fügen Sie Circle, Triangle und Rectangle hinzu.
        var shapes = new List<Shape>
        {
            new Rectangle(),
            new Triangle(),
            new Circle()
        };

        // Verwenden Sie eine foreach-Schleife, um über die abgeleiteten Klassen dieser Liste zu iterieren und die Draw-Methode für jedes Shape-Objekt aufzurufen
        foreach (var shape in shapes)
        {
            shape.Draw();
        }

        Console.WriteLine("Drücken Sie eine beliebige Taste, um zu beenden.");
        Console.ReadKey();
    }

}

Wenn der obige Code kompiliert und ausgeführt wird, liefert er die folgenden Ergebnisse:

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.

Das folgende Programm demonstriert die Berechnung der Fläche verschiedener Formen mithilfe der virtuellen Methode area():

Beispiel

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("Fläche der Elternklasse:");
         return 0;
      }
   }
   class Rectangle: Shape
   {
      public Rectangle( int a=0, int b=0): Basis(a, b)
      {

      }
      public override int area ()
      {
         Console.WriteLine(Die Fläche der Klasse Rectangle:);
         return (width * height);
      }
   }
   class Triangle: Shape
   {
      public Triangle(int a = 0, int b = 0): Basis(a, b)
      {
     
      }
      public override int area()
      {
         Console.WriteLine("Fläche der Triangle-Klasse:");
         return (width * height / 2);
      }
   }
   class Caller
   {
      public void CallArea(Shape sh)
      {
         int a;
         a = sh.area();
         Console.WriteLine("Fläche: {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();
      }
   }
}

Wenn der obige Code kompiliert und ausgeführt wird, liefert er die folgenden Ergebnisse:

Rectangle 类的面积:
面积:70
Triangle 类的面积:
面积:25
Weitere Erweiterungen