Classes abstratas e polimorfismo

Classes abstratas e interfaces são dois conceitos fundamentais da programação orientada a objetos em C#. Ambos servem para definir contratos e estruturas para outras classes, mas possuem diferenças importantes em uso e propósito.

Classes Abstratas

O que são:
Uma classe abstrata serve como modelo para outras classes e não pode ser instanciada diretamente. Ela pode conter métodos abstratos (sem implementação) e métodos concretos (com implementação), além de propriedades, construtores e outros membros.

Quando usar:
Use classes abstratas quando deseja fornecer uma implementação base parcial e forçar subclasses a implementar certos métodos.

Exemplo:

public abstract class Animal
{
    protected string Nome;

    public Animal(string nome)
    {
        Nome = nome;
    }

    public abstract void EmitirSom(); // Método abstrato

    public void Descricao()
    {
        Console.WriteLine("Sou um animal.");
    }
}

public class Cao : Animal
{
    public Cao(string nome) : base(nome) { }

    public override void EmitirSom()
    {
        Console.WriteLine($"{Nome} faz au au!");
    }
}

Interfaces

O que são:
Uma interface define apenas a assinatura de métodos, propriedades, eventos e indexadores, sem qualquer implementação. Classes e structs podem implementar múltiplas interfaces, o que permite simular herança múltipla.

Quando usar:
Use interfaces para definir contratos que podem ser compartilhados por classes diferentes, mesmo sem relação hierárquica.

Exemplo:

public interface IVoador
{
    void Voar();
}

public interface ICorredor
{
    void Correr();
}

public class Pato : IVoador, ICorredor
{
    public void Voar()
    {
        Console.WriteLine("O pato está voando!");
    }
    public void Correr()
    {
        Console.WriteLine("O pato está correndo!");
    }
}

Aqui, Pato implementa duas interfaces, adquirindo comportamentos de ambas.

Principais Diferenças

CaracterísticaClasse AbstrataInterface
InstanciaçãoNão pode ser instanciadaNão pode ser instanciada
Métodos com implementaçãoPode ter métodos implementados e abstratosNão possui implementação (até C# 8)
HerançaUma única classe baseMúltiplas interfaces
ConstrutoresPode ter construtoresNão possui construtores
Propriedades/CamposPode ter campos, propriedades e métodosSó propriedades e métodos

Quando usar cada uma?

  • Classe abstrata:
    Quando existe uma relação de “é um tipo de” e parte da implementação pode ser compartilhada entre subclasses.
  • Interface:
    Quando deseja garantir que diferentes classes implementem certos métodos, independentemente da hierarquia.

Resumo prático

  • Use classes abstratas para criar uma base comum com implementação compartilhada.
  • Use interfaces para definir contratos e garantir comportamentos em múltiplas classes, inclusive simulando herança múltipla.