CodeGym /Cursos /C# SELF /Conceito de Herança

Conceito de Herança

C# SELF
Nível 20 , Lição 0
Disponível

1. Introdução

Herança na programação é bem parecida com herança na vida real. Por exemplo, você pode herdar dos seus pais a cor dos olhos, o formato do nariz ou até talento pra desenhar. Você ganha essas características "por padrão", não precisa criar do zero. Mas ao mesmo tempo, pode desenvolver suas próprias características únicas, que seus pais não têm.

Na programação, funciona de um jeito parecido:

  • Uma classe (vamos chamar de classe base ou classe mãe, às vezes superclasse) define características comuns (propriedades) e comportamentos (métodos) que todos os seus "filhos" vão ter.
  • Outra classe (chamada de classe derivada ou classe filha, às vezes subclasse) herda todas essas características do seu "pai". Ela automaticamente recebe todas as propriedades e métodos public e protected da classe base. Não precisa declarar de novo.
  • Além disso, a classe derivada pode adicionar suas próprias propriedades e métodos únicos, que não existem na classe mãe.
  • Às vezes, a classe derivada pode até alterar o comportamento dos métodos herdados (mas isso a gente vê nas próximas aulas, chama-se polimorfismo).

O conceito chave da herança é a frase "é-um-alguma-coisa" (is-a relationship). Imagina que você tá criando um jogo com magos, guerreiros e arqueiros:

  • Guerreiro é um Personagem.
  • Mago é um Personagem.
  • Arqueiro é um Personagem.

Se Guerreiro é um Personagem, então ele tem tudo que qualquer Personagem tem, mais algo próprio, exclusivo do Guerreiro.

2. Sintaxe da Herança

Bora ver um exemplo e codar um pouco.

O básico da sintaxe


// Classe base
public class Animal
{
    public string Name { get; set; }

    public void Move()
    {
        Console.WriteLine($"{Name} se move.");
    }
}

// Classe filha
public class Dog : Animal
{
    public void Bark()
    {
        Console.WriteLine($"{Name} late: Au!");
    }
}

Repara nos dois pontos depois do nome da classe Dog. Aqui a gente diz: Dog herda tudo que tem em Animal.

Tudo que é public e protected em Animal aparece em Dog!

Usando herança

Bora usar essas classes no nosso app de console:


var dog = new Dog();
dog.Name = "Sharik"; // propriedade Name herdada de Animal
dog.Move();         // método Move herdado de Animal
dog.Bark();         // método próprio de Dog

// Saída:
// Sharik se move.
// Sharik late: Au!

Dá pra criar um gato também, pra variar o "zoológico":

public class Cat : Animal
{
    public void Meow()
    {
        Console.WriteLine($"{Name} mia: Miau!");
    }
}

var cat = new Cat();
cat.Name = "Murka";
cat.Move();
cat.Meow();

3. Como a herança economiza esforço

Quando você tem várias entidades parecidas, não precisa copiar código toda hora. Herança é tipo um master copy: você define a lógica uma vez, e todos os filhos recebem.

Visualizando: Árvore de herança


.   Animal
     /    \
  Dog    Cat
Esquema de herança das classes
Classe Propriedade Name Método Move Método próprio
Animal + + -
Dog + + Bark()
Cat + + Meow()

Outro exemplo — expandindo o app

Imagina que você quer criar um sistema pra registrar diferentes tipos de pessoas. Lembra do jeito antigo:

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

// Agora adiciona um funcionário
public class Employee
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Position { get; set; }
}

Nada prático! Os dados do nome estão duplicados. Com herança, fica do jeito certo:


public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

public class Employee : Person
{
    public string Position { get; set; }
}

public class Student : Person
{
    public int Grade { get; set; }
}
Herança pra eliminar código duplicado

Agora Employee e Student já têm FirstName e LastName — não precisa escrever de novo. Dá pra imaginar que agora você expande o sistema fácil pra vários papéis.

Essa é a mágica da herança: a gente descreve as características comuns na classe base uma vez, e depois só "expande" a funcionalidade nas classes derivadas, adicionando detalhes específicos.

4. Vantagens da herança

Reaproveitamento de código (Code Reusability): Essa é a vantagem mais óbvia. Você não precisa escrever o mesmo código em vários lugares. Escreveu uma vez — usou várias. Seu código fica mais seco e limpo (no mundo dev a galera fala "Don't Repeat Yourself" — DRY, "Não se repita").

Facilita a manutenção (Easier Maintenance): Se você precisa mudar a lógica de movimento, muda só num lugar — na classe base Animal. Todas as classes derivadas pegam essa mudança automaticamente. Imagina quanto tempo isso economiza num projeto grande!

Criação de hierarquias (Creating Hierarchies): Herança permite modelar relações "é-um-alguma-coisa" do mundo real, criando estruturas lógicas e fáceis de entender. Guerreiro é um Personagem, Mago é um Personagem. Isso deixa seu código mais organizado e fácil de sacar.

Base para polimorfismo: Mesmo que a gente ainda não tenha visto polimorfismo a fundo, herança é a base dele. Polimorfismo deixa você trabalhar com objetos de diferentes classes derivadas usando a interface comum da classe base. Por exemplo, você pode ter uma lista de todos os Animals (seja Dog, Cat ou outros bichos) e chamar o método Move neles, sem se preocupar com o tipo exato de cada animal. Isso é muito poderoso, e a gente vai voltar nesse assunto!

5. Nuances e detalhes da herança

Herança simples em C#: Diferente de algumas linguagens (tipo C++), C# só suporta herança simples. Ou seja, uma classe só pode herdar de uma classe base. Não dá pra herdar de Animal e, sei lá, de Vehicle ao mesmo tempo (se essa classe existisse).

Todas as classes herdam implicitamente de object: Curiosidade! Se você não especifica uma classe base, sua classe automaticamente herda de System.Object. Essa é a classe mais básica do .NET, e ela traz métodos fundamentais como ToString(), Equals(), GetHashCode(). Então, quando você sobrescreve ToString() nas suas classes, na real você tá sobrescrevendo um método herdado de object!

Construtores não são herdados: A classe derivada não herda os construtores da classe base. Você tem que definir os construtores na classe derivada. Mas, se a classe base tem um construtor com parâmetros, você DEVE chamar um dos construtores da classe base no construtor da derivada. Isso é feito com a palavra-chave base.

Membros privados não são acessíveis: Os membros private da classe base não são acessíveis diretamente na classe derivada. Eles existem no objeto, mas você não pode acessar pelo nome no código da derivada. Se quiser que membros sejam acessíveis pras classes filhas, mas não pro mundo todo, usa o modificador protected.

6. Visualizando a hierarquia

Pra entender melhor as relações de herança, a galera costuma usar diagramas. Um dos mais comuns é o diagrama de classes UML (Unified Modeling Language). Pro exemplo simples dos animais, ficaria assim:

classDiagram
    class Animal {
        + string Name
        + Move()
    }

    class Dog {
        + Bark()
    }

    class Cat {
        + Meow()
    }

    Animal <|-- Dog : herda
    Animal <|-- Cat : herda
Diagrama UML de classes pro exemplo de herança

Nesse diagrama, a seta com triângulo vazio (de Dog pra Animal, de Cat pra Animal) significa relação de herança: "é-um-alguma-coisa" (is-a relationship).

7. Herança na prática

Herança não é só conceito acadêmico, é um dos pilares da programação moderna, super usado em projetos reais:

Desenvolvimento de interface gráfica (GUI): No WPF, WinForms, MAUI (frameworks pra criar apps desktop em .NET), quase todos os controles (botões, caixas de texto, janelas) herdam de uma classe base comum, tipo Control ou UIElement. Isso faz eles terem propriedades comuns, tipo tamanho, posição, visibilidade, e métodos comuns, tipo tratamento de eventos.
Por exemplo, Button é um Control, e TextBox é um Control.

Engines de jogos: Herança é perfeita pra criar hierarquias de objetos de jogo: GameObjectCharacterPlayer/Enemy ou VehicleCar/Motorcycle.

Trabalhando com banco de dados (ORM): Em frameworks como Entity Framework Core, você geralmente define uma classe base pra todas as suas entidades, tipo BaseEntity, que pode ter propriedades como Id (identificador no banco) ou CreatedAt (data de criação). Todas as entidades concretas (User, Product, Order) vão herdar de BaseEntity e já ganham essas propriedades.

Testes: Herança é usada em frameworks de teste (tipo xUnit, NUnit), onde você pode criar classes base de teste com lógica comum de inicialização e limpeza, e as classes de teste concretas herdam delas.

Bibliotecas e frameworks: A própria biblioteca padrão do .NET usa herança pra caramba. Muitas coleções e tipos herdam de classes base comuns ou implementam interfaces comuns (sobre interfaces a gente fala depois).

Em entrevistas de C# e .NET, perguntas sobre herança, seus princípios (DRY, "is-a"), e diferenças pra outros conceitos (tipo composição ou interfaces) são básicas e aparecem direto. Saber explicar o que é, e dar exemplos reais ou de código — é um baita diferencial.

Então, tá vendo? Herança não é só "firula" da linguagem, é uma ferramenta poderosa pra estruturar código, reduzir duplicação e criar sistemas logicamente conectados. É a chave pra escrever código escalável e fácil de manter.

Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION