Menu
Coddy logo textTech

Polimorfismo: Compilação vs Execução

Parte da seção Programação Orientada a Objetos do Journey de C# da Coddy. Lição 25 de 70.

Polimorfismo significa "muitas formas" - a capacidade de o mesmo código se comportar de maneira diferente dependendo do contexto. O C# suporta dois tipos distintos de polimorfismo, e entender quando cada um é resolvido ajuda você a escrever códigos mais flexíveis.

Polimorfismo de tempo de compilação (também chamado de polimorfismo estático) é resolvido pelo compilador antes de seu programa ser executado. A sobrecarga de métodos é o exemplo principal - múltiplos métodos compartilham o mesmo nome, mas possuem parâmetros diferentes:

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);       // O compilador escolhe a versão int
calc.Add(5.0, 3.0);   // O compilador escolhe a versão double

O compilador examina os tipos de argumentos e seleciona o método correto em tempo de compilação. Esta decisão é fixada antes mesmo de o programa ser executado.

Polimorfismo de tempo de execução (polimorfismo dinâmico) é resolvido enquanto o programa é executado. Isso acontece com métodos virtual e override - o tipo real do objeto determina qual método será executado:

Animal pet = new Dog();  // Declarado como Animal, na verdade um Dog
pet.Speak();             // Chama o Speak() de Dog em tempo de execução

O compilador não sabe qual Speak() será executado - essa decisão acontece em tempo de execução com base no tipo real do objeto. É isso que torna o polimorfismo baseado em herança tão poderoso para construir sistemas flexíveis e extensíveis.

challenge icon

Desafio

Fácil

Vamos criar um sistema de conversão que demonstra os dois tipos de polimorfismo em ação. Você criará uma classe que usa sobrecarga de métodos (polimorfismo em tempo de compilação) junto com uma hierarquia de herança que usa métodos virtual/override (polimorfismo em tempo de execução).

Você organizará seu código em quatro arquivos:

  • Converter.cs: Defina uma classe Converter no namespace Conversion. Essa classe demonstra o polimorfismo em tempo de compilação por meio da sobrecarga de métodos. Crie três métodos Convert sobrecarregados:
    • Convert(int value) retorna "Integer: {value}"
    • Convert(double value) retorna "Double: {value}"
    • Convert(string value) retorna "String: {value}"
  • Shape.cs: Defina uma classe base Shape no namespace Conversion. Essa classe tem uma propriedade Name (string) e um construtor que a define. Inclua um método virtual chamado Describe() que retorna "This is a {Name}".
  • Circle.cs: Defina uma classe Circle no namespace Conversion que herda de Shape. Adicione uma propriedade Radius (double). O construtor aceita um raio e passa "Circle" para o construtor da classe base. Substitua Describe() para retornar "This is a Circle with radius {Radius}".
  • Program.cs: No seu arquivo principal, demonstre os dois tipos de polimorfismo. Primeiro, crie um Converter e chame os três métodos sobrecarregados com valores de entrada. Em seguida, crie um Circle, armazene-o em uma variável Shape e chame Describe() para demonstrar o polimorfismo em tempo de execução.

Você receberá quatro entradas:

  • Um valor inteiro
  • Um valor double
  • Um valor string
  • Um raio de círculo (double)

Imprima a saída neste formato:

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

Por exemplo, se as entradas forem 42, 3.14, Hello e 5.5, a saída deverá ser:

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

Observe a diferença principal: o compilador decide qual método Convert chamar com base nos tipos dos argumentos em tempo de compilação, enquanto o método Describe() é resolvido em tempo de execução com base no tipo real do objeto, embora ele esteja armazenado em uma variável Shape!

Experimente você mesmo

using System;
using Conversion;

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

        // TODO: Demonstrar Polimorfismo de Tempo de Compilação
        // Criar um objeto Converter e chamar todos os três métodos Convert sobrecarregados
        Console.WriteLine("Compile-time Polymorphism:");
        // Chamar Convert com intValue, doubleValue e stringValue

        // TODO: Demonstrar Polimorfismo de Tempo de Execução
        // Criar um objeto Circle e armazená-lo em uma variável Shape
        // Em seguida, chamar Describe() na variável Shape
        Console.WriteLine("Runtime Polymorphism:");
        // Criar Circle e chamar Describe()
    }
}
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Programação Orientada a Objetos

Pratique por conta própria: Compilador de C# online