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 construir um sistema conversor que demonstra os dois tipos de polimorfismo em ação. Você criará uma classe que usa sobrecarga de métodos (polimorfismo de tempo de compilação) juntamente com uma hierarquia de herança que usa métodos virtual/override (polimorfismo de tempo de execução).

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

  • Converter.cs: Defina uma classe Converter no namespace Conversion. Esta classe demonstra o polimorfismo de tempo de compilação através 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. Esta classe possui 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 base. Sobrescreva Describe() para retornar "This is a Circle with radius {Radius}".
  • Program.cs: No seu arquivo principal, demonstre ambos os tipos de polimorfismo. Primeiro, crie um Converter e chame todos 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 mostrar o polimorfismo de 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 deve 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 fundamental: o compilador decide qual método Convert chamar com base nos tipos de argumentos em tempo de compilação, enquanto o método Describe() é resolvido em tempo de execução com base no tipo real do objeto, mesmo que ele esteja armazenado em uma variável Shape!

Folha de consulta

Polimorfismo significa "muitas formas" - a capacidade de o mesmo código se comportar de maneira diferente dependendo do contexto.

Polimorfismo de tempo de compilação (polimorfismo estático) é resolvido pelo compilador antes de o programa ser executado. A sobrecarga de métodos é o principal exemplo:

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.

Polimorfismo de tempo de execução (polimorfismo dinâmico) é resolvido enquanto o programa é executado usando métodos virtual e override:

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

O tipo real do objeto determina qual método é executado em tempo de execução, não o tipo de variável declarado.

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