Menu
Coddy logo textTech

Polimorfismo: Compilación vs. Ejecución

Parte de la sección Programación Orientada a Objetos del Journey de C# de Coddy — lección 25 de 70.

El polimorfismo significa "muchas formas": la capacidad de que el mismo código se comporte de manera diferente según el contexto. C# admite dos tipos distintos de polimorfismo, y comprender cuándo se resuelve cada uno ayuda a escribir código más flexible.

El polimorfismo en tiempo de compilación (también llamado polimorfismo estático) es resuelto por el compilador antes de que se ejecute su programa. La sobrecarga de métodos es el ejemplo principal: múltiples métodos comparten el mismo nombre pero tienen diferentes parámetros:

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);       // El compilador elige la versión int
calc.Add(5.0, 3.0);   // El compilador elige la versión double

El compilador examina los tipos de argumentos y selecciona el método correcto en tiempo de compilación. Esta decisión queda fijada antes de que el programa se ejecute.

Polimorfismo en tiempo de ejecución (polimorfismo dinámico) se resuelve mientras el programa se ejecuta. Esto sucede con los métodos virtual y override: el tipo real del objeto determina qué método se ejecuta:

Animal pet = new Dog();  // Declarado como Animal, en realidad un Dog
pet.Speak();             // Llama al Speak() de Dog en tiempo de ejecución

El compilador no sabe qué Speak() se ejecutará; esa decisión ocurre en tiempo de ejecución basándose en el tipo real del objeto. Esto es lo que hace que el polimorfismo basado en herencia sea tan potente para construir sistemas flexibles y extensibles.

challenge icon

Desafío

Fácil

Vamos a construir un sistema convertidor que demuestre ambos tipos de polimorfismo en acción. Crearás una clase que utiliza la sobrecarga de métodos (polimorfismo en tiempo de compilación) junto con una jerarquía de herencia que utiliza métodos virtual/override (polimorfismo en tiempo de ejecución).

Organizarás tu código en cuatro archivos:

  • Converter.cs: Define una clase Converter en el espacio de nombres Conversion. Esta clase demuestra el polimorfismo en tiempo de compilación a través de la sobrecarga de métodos. Crea tres métodos Convert sobrecargados:
    • Convert(int value) devuelve "Integer: {value}"
    • Convert(double value) devuelve "Double: {value}"
    • Convert(string value) devuelve "String: {value}"
  • Shape.cs: Define una clase base Shape en el espacio de nombres Conversion. Esta clase tiene una propiedad Name (string) y un constructor que la establece. Incluye un método virtual llamado Describe() que devuelve "This is a {Name}".
  • Circle.cs: Define una clase Circle en el espacio de nombres Conversion que hereda de Shape. Añade una propiedad Radius (double). El constructor acepta un radio y pasa "Circle" al constructor base. Sobrescribe Describe() para que devuelva "This is a Circle with radius {Radius}".
  • Program.cs: En tu archivo principal, demuestra ambos tipos de polimorfismo. Primero, crea un Converter y llama a los tres métodos sobrecargados con valores de entrada. Luego crea un Circle, almacénalo en una variable de tipo Shape y llama a Describe() para mostrar el polimorfismo en tiempo de ejecución.

Recibirás cuatro entradas:

  • Un valor entero
  • Un valor double
  • Un valor de cadena (string)
  • Un radio de círculo (double)

Imprime la salida en este formato:

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

Por ejemplo, si las entradas son 42, 3.14, Hello y 5.5, la salida debería ser:

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

Observa la diferencia clave: el compilador decide qué método Convert llamar basándose en los tipos de argumentos en tiempo de compilación, mientras que el método Describe() se resuelve en tiempo de ejecución basándose en el tipo de objeto real, ¡aunque esté almacenado en una variable Shape!

Hoja de referencia

El polimorfismo significa "muchas formas": la capacidad de que el mismo código se comporte de manera diferente según el contexto.

El polimorfismo en tiempo de compilación (polimorfismo estático) es resuelto por el compilador antes de que se ejecute el programa. La sobrecarga de métodos es el ejemplo principal:

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);       // El compilador elige la versión int
calc.Add(5.0, 3.0);   // El compilador elige la versión double

El compilador examina los tipos de argumentos y selecciona el método correcto en tiempo de compilación.

El polimorfismo en tiempo de ejecución (polimorfismo dinámico) se resuelve mientras el programa se ejecuta utilizando los métodos virtual y override:

Animal pet = new Dog();  // Declarado como Animal, en realidad es un Dog
pet.Speak();             // Llama al Speak() de Dog en tiempo de ejecución

El tipo real del objeto determina qué método se ejecuta en tiempo de ejecución, no el tipo de variable declarado.

Pruébalo tú mismo

using System;
using Conversion;

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

        // TODO: Demonstrate Compile-time Polymorphism
        // Crear un objeto Converter y llamar a los tres métodos Convert sobrecargados
        Console.WriteLine("Compile-time Polymorphism:");
        // Llamar a Convert con intValue, doubleValue y stringValue

        // TODO: Demonstrate Runtime Polymorphism
        // Crear un objeto Circle y almacenarlo en una variable Shape
        // Luego llamar a Describe() en la variable Shape
        Console.WriteLine("Runtime Polymorphism:");
        // Crear Circle y llamar a Describe()
    }
}
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Programación Orientada a Objetos