Polimorfismo em C#: Binding Estático vs Dinâmico Explicado
Polimorfismo significa "muitas formas". Em POO, expressa-se como "uma interface, múltiplas funções".
Pode ser estático (resposta determinada em tempo de compilação) ou dinâmico (decidido em tempo de execução).
Polimorfismo Estático
Mecanismo de vincular função a objeto em tempo de compilação = early binding / static binding. Duas técnicas:
- Sobrecarga de funções (Function Overloading)
- Sobrecarga de operadores (Operator Overloading)
Sobrecarga de Funções
Múltiplas definições para mesmo nome no mesmo escopo. Devem diferir por tipos/número de argumentos. Não pode diferir apenas por tipo de retorno.
Exemplo
class Printdata
{
void Print(int i) { Console.WriteLine("Printing int: {0}", i); }
void Print(double f) { Console.WriteLine("Printing float: {0}", f); }
void Print(string s) { Console.WriteLine("Printing string: {0}", s); }
}
// Uso:
Printdata p = new Printdata();
p.Print(5);
p.Print(500.263);
p.Print("Hello C#");
Saída:
Printing int: 5
Printing float: 500.263
Printing string: Hello C#
Polimorfismo Dinâmico
Classes abstratas fornecem implementação parcial de interface. Completada quando classe derivada herda. Contêm métodos abstratos implementados pela derivada.
Regras de Classes Abstratas
- Não se pode instanciar classe abstrata.
- Não se pode declarar método abstrato fora de classe abstrata.
- Classe
sealednão pode ser herdada; classes abstratas não podem sersealed.
Exemplo: Classe Abstrata
abstract class Shape
{
public abstract int Area();
}
class Rectangle : Shape
{
private int length, width;
public Rectangle(int a = 0, int b = 0) { length = a; width = b; }
public override int Area()
{
Console.WriteLine("Rectangle class area:");
return width * length;
}
}
Funções Virtuais
Quando quer que função seja implementada em classe herdada, use virtual. Implementação difere por classe derivada; chamada decidida em runtime.
Polimorfismo dinâmico = classes abstratas + funções virtuais.
Exemplo com Virtual/Override
class Shape
{
protected int width, height;
public Shape(int a = 0, int b = 0) { width = a; height = b; }
public virtual int Area()
{
Console.WriteLine("Parent class area:");
return 0;
}
}
class Rectangle : Shape
{
public Rectangle(int a = 0, int b = 0) : base(a, b) { }
public override int Area()
{
Console.WriteLine("Rectangle class area:");
return width * height;
}
}
class Triangle : Shape
{
public Triangle(int a = 0, int b = 0) : base(a, b) { }
public override int Area()
{
Console.WriteLine("Triangle class area:");
return width * height / 2;
}
}
class Caller
{
public void CallArea(Shape sh)
{
int a = sh.Area();
Console.WriteLine("Area: {0}", a);
}
}
// Uso:
Caller c = new Caller();
c.CallArea(new Rectangle(10, 7)); // Area: 70
c.CallArea(new Triangle(10, 5)); // Area: 25
Linguagem C
- Classes e Objetos em C#: Fundamentos para POO Robusta
- Entendendo Modificadores de Acesso em C#: Public, Private, Protected, Internal e Mais
- Palavra-chave Static em C#: Dominando Variáveis, Métodos e Classes Estáticas
- Dominando Classes e Métodos Abstratos em C#: Guia Prático
- Entendendo Classes Aninhadas em C#: Definição, Uso e Herança
- Entendendo Classes e Métodos Parciais em C#
- Dominando Templates de Classe em C++: Um Guia Prático
- Dominando Classes Internas Anônimas em Java: Definição, Sintaxe e Exemplos Práticos
- Dominando Java ObjectOutputStream: Serialização, Métodos e Exemplos Práticos
- Dominando Java Generics – Construindo Código Reutilizável e Type-Safe