Polimorfismo permite que codigo chame operacoes num tipo base enquanto executa o comportamento do tipo derivado em runtime. E o princpio que torna possivel o Open/Closed Principle (OCP) do SOLID.

O que e polimorfismo?

Polimorfismo ("muitas formas") permite que um unico contrato (classe base ou interface) tenha multiplas implementacoes. O runtime decide qual metodo executar baseado no tipo real do objeto, nao no tipo da variavel.

extendsextendsimplementsimplementsimplementsShapeabstract classCirclesealed classRectanglesealed classIAreainterfaceTrianglesealed classVirtual dispatch: chamadas via Shape despacham para Circle ou Rectangle em runtime

Formas de polimorfismo em C#

FormaMecanismoDispatchQuando usar
Subtyping (heranca)virtual + overrideDinamico (runtime)Comportamento extensivel com estado compartilhado
Interfacesinterface + implementacaoDinamico (runtime)Desacoplamento, multiplas capacidades, testabilidade
Abstract classesabstract + overrideDinamico (runtime)Template Method, forcar implementacao com base compartilhada
Pattern matchingswitch / isExplicito (compile-time check)Comportamento one-off sem modificar tipos
DelegatesFunc<T> / Action<T>ComposicaoStrategy leve, sem heranca
new (hiding)new keywordEstatico (compile-time)Evitar β€” nao e polimorfismo real

Virtual dispatch β€” como funciona

Quando voce declara um metodo como virtual ou abstract, o CLR cria uma virtual method table (vtable) para cada tipo. Em runtime:

  1. O CLR olha o tipo real do objeto (nao o tipo da variavel)
  2. Busca na vtable desse tipo qual metodo corresponde
  3. Executa o metodo da classe derivada (override)

Isso significa que Shape s = new Circle(2); s.Area(); executa Circle.Area(), mesmo que a variavel seja do tipo Shape.

Regras fundamentais

abstract

  • Nao tem implementacao na classe base
  • Classes derivadas devem implementar
  • A classe base tambem deve ser abstract
  • Nao pode ser instanciada diretamente

virtual

  • Tem implementacao padrao na classe base
  • Classes derivadas podem fazer override
  • Se nao fizerem override, herdam o comportamento base
  • A classe base pode ser concreta

sealed override

  • Faz override do metodo base
  • Impede que classes mais derivadas facam override novamente
  • Otimizacao: o JIT pode fazer devirtualization
  • Seguranca: garante comportamento final

new (hiding)

  • Nao e polimorfismo β€” esconde o membro base
  • O metodo chamado depende do tipo da variavel, nao do objeto
  • Gera warning CS0108 se omitido
  • Evitar em producao β€” causa confusao
Qual a diferenca entre virtual e abstract?
abstract nao tem corpo β€” forca a classe derivada a implementar. virtual tem implementacao padrao β€” a classe derivada pode opcionalmente fazer override. Ambos participam de virtual dispatch (polimorfismo runtime).
O que acontece se eu chamar um metodo virtual no construtor da classe base?
O virtual dispatch ja esta ativo, entao o metodo da classe derivada e chamado β€” mas o construtor da derivada ainda nao rodou. Isso pode causar bugs porque o objeto esta em estado inconsistente. Evite chamar metodos virtuais em construtores.
Por que sealed override melhora performance?
Com sealed override, o JIT sabe que nao existem mais overrides possiveis. Isso permite devirtualization β€” o JIT substitui a chamada virtual por uma chamada direta, eliminando a indirection da vtable. Em hot paths, isso pode ter impacto mensuravel.