C# Polimorfismo

El polimorfismo es la capacidad de un mismo comportamiento de tener múltiples formas o manifestaciones diferentes.

PolimorfismoSignifica tener múltiples formas. En el paradigma de programación orientada a objetos, el polimorfismo suele manifestarse como "una interfaz, múltiples funciones".

El polimorfismo puede ser estático o dinámico. En elpolimorfismo estático, las respuestas de las funciones ocurren en tiempo de compilación. En elpolimorfismo dinámico, las respuestas de las funciones ocurren en tiempo de ejecución.

En C#, todos los tipos son polimórficos porque todos los tipos, incluidos los tipos definidos por el usuario, heredan de Object.

El polimorfismo es la misma interfaz que, al usar diferentes instancias, ejecuta diferentes operaciones, como se muestra en la figura:

En la vida real, por ejemplo, la acción de presionar la tecla F1:

  • Si actualmente se encuentra en la interfaz de Flash, aparecerá el documento de ayuda de AS 3;
  • Si se encuentra en Word, aparecerá la ayuda de Word;
  • Si está en Windows, aparecerá la ayuda y el soporte de Windows.

El mismo evento que ocurre en diferentes objetos produce diferentes resultados.

Polimorfismo estático

El mecanismo de conexión entre funciones y objetos en tiempo de compilación se denomina enlace temprano, también conocido como enlace estático. C# proporciona dos técnicas para implementar el polimorfismo estático, a saber:

  • Sobrecarga de funciones
  • Sobrecarga de operadores

La sobrecarga de operadores se discutirá en el siguiente capítulo; a continuación hablaremos de la sobrecarga de funciones.


Sobrecarga de funciones

No se permite que las distintas sobrecargas difieran solo en el tipo de retorno de la declaración de la función.

El siguiente ejemplo demuestra varias funciones con el mismo nombreAdd(), que se utilizan para sumar diferentes números de parámetros:

Ejemplo

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

El siguiente ejemplo demuestra varias funciones con el mismo nombreprint(), que se utilizan para imprimir diferentes tipos de datos:

Ejemplo

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

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

      void print(string s)
      {
         Console.WriteLine("Salida de cadena: {0}", s);
      }
      static void Main(string[] args)
      {
         Printdata p = new Printdata();
         // Llama a print para imprimir un entero
         p.print(1);
         // Llama a print para imprimir un número flotante
         p.print(1.23);
         // Llama a print para imprimir una cadena
         p.print("Hello Ejemplo");
         Console.ReadKey();
      }
   }
}

Cuando el código anterior se compila y ejecuta, produce los siguientes resultados:

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

Polimorfismo dinámico

C# le permite usar la palabra claveabstractcrear clases abstractas para proporcionar la implementación parcial de una interfaz. Cuando una clase derivada hereda de dicha clase abstracta, la implementación se completa.La clase abstractacontiene métodos abstractos, que pueden ser implementados por las clases derivadas. Las clases derivadas tienen una funcionalidad más especializada.

Tenga en cuenta las siguientes reglas sobre las clases abstractas:

  • No se puede crear una instancia de una clase abstracta.
  • No se puede declarar un método abstracto fuera de una clase abstracta.
  • Al colocar la palabra clavesealedsealed delante de la definición de la clase, se puede declarar la clase comoclase sellada. Cuando una clase se declara comosealedsealed, no puede ser heredada. Una clase abstracta no puede declararse como sealed.

El siguiente programa demuestra una clase abstracta:

Ejemplo

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(El área de la clase Rectangle:);
         return (width * length);
      }
   }

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

Cuando el código anterior se compila y ejecuta, produce los siguientes resultados:

Rectangle 类的面积:
面积: 70

Cuando una función definida en una clase necesita ser implementada en una clase heredada, se puede usarun método virtual.。

Un método virtual se declara con la palabra clavevirtualvirtual.

Los métodos virtuales pueden tener diferentes implementaciones en diferentes clases heredadas.

La llamada a un método virtual ocurre en tiempo de ejecución.

El polimorfismo dinámico se implementa medianteclases abstractasyy métodos virtuales.

El siguiente ejemplo crea la clase base Shape y las clases derivadas Circle, Rectangle y Triangle. La clase Shape proporciona un método virtual llamado Draw, que se reemplaza en cada clase derivada para dibujar la forma específica de esa clase.

Ejemplo

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étodo virtual
    public virtual void Draw()
    {
        Console.WriteLine("Ejecutar la tarea de dibujo de la clase base");
    }
}

class Circle : Shape
{
    public override void Draw()
    {
        Console.WriteLine("Dibuja un círculo");
        base.Draw();
    }
}
class Rectangle : Shape
{
    public override void Draw()
    {
        Console.WriteLine("Dibujar un rectángulo");
        base.Draw();
    }
}
class Triangle : Shape
{
    public override void Draw()
    {
        Console.WriteLine("Dibujar un triángulo");
        base.Draw();
    }
}

class Program
{
    static void Main(string[] args)
    {
        // Crear un objeto List<Shape> y agregarle Circle, Triangle y Rectangle
        var shapes = new List<Shape>
        {
            new Rectangle(),
            new Triangle(),
            new Circle()
        };

        // Use un bucle foreach para iterar sobre las clases derivadas en esta lista y llamar al método Draw en cada objeto Shape.
        foreach (var shape in shapes)
        {
            shape.Draw();
        }

        Console.WriteLine("Presione cualquier tecla para salir.");
        Console.ReadKey();
    }

}

Cuando el código anterior se compila y ejecuta, produce los siguientes resultados:

Dibujar un rectángulo
Ejecutar la tarea de dibujo de la clase base
Dibujar un triángulo
Ejecutar la tarea de dibujo de la clase base
Dibujar un círculo
Ejecutar la tarea de dibujo de la clase base
Presione cualquier tecla para salir.

El siguiente programa demuestra el cálculo del área de diferentes formas usando el método virtual area():

Ejemplo

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("Área de la clase padre:");
         return 0;
      }
   }
   class Rectangle: Shape
   {
      public Rectangle( int a=0, int b=0): base(a, b)
      {

      }
      public override int area ()
      {
         Console.WriteLine(El área de la clase Rectangle:);
         return (width * height);
      }
   }
   class Triangle: Shape
   {
      public Triangle(int a = 0, int b = 0): base(a, b)
      {
     
      }
      public override int area()
      {
         Console.WriteLine(Área de la clase Triangle:);
         return (width * height / 2);
      }
   }
   class Caller
   {
      public void CallArea(Shape sh)
      {
         int a;
         a = sh.area();
         Console.WriteLine("Área: {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();
      }
   }
}

Cuando el código anterior se compila y ejecuta, produce los siguientes resultados:

Rectangle 类的面积:
面积:70
Triangle 类的面积:
面积:25
Otras extensiones