CodeGym /Cursos /JAVA 25 SELF /Conceito de herança, sintaxe de extends

Conceito de herança, sintaxe de extends

JAVA 25 SELF
Nível 17 , Lição 0
Disponível

1. O que é herança?

Herança é um mecanismo que permite criar uma nova classe com base em uma já existente, “herdando” suas propriedades e métodos. A nova classe é chamada de subclasse (ou classe filha), e a classe original é a classe pai (ou classe base).

É como fazer um novo bolo a partir de uma receita antiga: você pega o que há de melhor, adiciona alguns ingredientes novos — e voilà, você já tem o “Bolo da vovó com ingrediente secreto”.

  • Classe pai — contém propriedades e comportamentos comuns.
  • Subclasse — herda tudo isso e ainda pode adicionar algo próprio ou alterar o comportamento.

Por exemplo, “Gato é um Animal”: todo gato é um animal, mas nem todo animal é um gato. Animal pode ser a classe base, e Gato — sua subclasse. O mesmo vale para Cachorro, por exemplo.
Ou “Círculo é uma Figura”: todo círculo é uma figura, mas nem toda figura é um círculo. Figura pode ser a classe pai, e Círculo e Triângulo — seus herdeiros. Em Java, esses relacionamentos são implementados com a palavra‑chave extends.

Para que serve a herança?

Pergunta de um milhão: por que não simplesmente copiar o código de uma classe para outra? Por que inventaram a herança?

  • Reutilização de código: Tudo o que é comum vai para a classe base. Não é necessário duplicar campos e métodos — eles aparecem automaticamente nas subclasses. Por exemplo, em um sistema para universidade, a classe base pode ser “pessoa”, que tem pelo menos nome e data de nascimento, enquanto “estudante” e “professor” são subclasses com suas próprias propriedades.
  • Extensão e especialização: É possível adicionar novos campos e métodos ou modificar os existentes apenas onde necessário. Todos os animais emitem sons, mas o gato mia e o cão late. Além disso, você pode adicionar ao gato a habilidade de escalar árvores (algo que a classe base não tem).
  • Estruturação de hierarquias: O código fica mais lógico e compreensível. Por exemplo, se você tem as classes Animal, Dog, Cat, fica claro que Dog e Cat são casos específicos de Animal.

Exemplo. Se não existisse herança em Java, você teria que copiar métodos como eat(), sleep() e o campo name para cada classe de animal. E se amanhã for necessário adicionar o método breathe(), seria preciso alterar dezenas de classes! Com herança, basta adicionar a capacidade de respirar na classe base.

2. Sintaxe da herança: extends

Como declarar herança em Java? É bem simples: use a palavra‑chave extends.

class RoditelskiyKlass {
    // campos e métodos
}

class Podklass extends RoditelskiyKlass {
    // campos e métodos adicionais
}

Exemplo 1: Animais

// Classe pai
class Animal {
    String name;

    void eat() {
        System.out.println(name + " come.");
    }
}

// Subclasse
class Cat extends Animal {
    void meow() {
        System.out.println(name + " diz: Miau!");
    }
}

O que está acontecendo aqui?

  • A classe Cat herda todos os campos e métodos da classe Animal.
  • Ou seja, Cat já tem o campo name e o método eat(), mesmo sem os termos escrito explicitamente.
  • Além disso, Cat tem seu próprio método meow().

Uso

public class Main {
    public static void main(String[] args) {
        Cat kitty = new Cat();
        kitty.name = "Barsik";
        kitty.eat();      // Barsik come.  (herdado)
        kitty.meow();     // Barsik diz: Miau! (método próprio)
    }
}

Voilà! Obtivemos uma nova classe com o mínimo de código, evitando duplicação.

3. O que exatamente uma subclasse herda?

Em Java, uma subclasse herda:

  • Todos os campos e métodos públicos (public) e protegidos (protected) da classe base.
  • Todos os membros package-private, se a subclasse estiver no mesmo pacote.

Não herda:

  • Construtores (eles precisam ser declarados explicitamente na subclasse).
  • Campos e métodos privados (private) (acessíveis apenas dentro da própria classe base).
  • Blocos estáticos de inicialização (não são herdados, mas cada classe pode ter os seus).
  • Membros com acesso package-private, se a subclasse estiver em outro pacote.

Ilustração

class Animal {
    public String name;
    private int age;

    public void eat() { 
        System.out.println("Comendo"); 
    }
    private void secret() { 
        System.out.println("Segredo!"); 
    }
}

class Dog extends Animal {
    public void bark() { 
        System.out.println("Au!"); 
    }
}
  • Dog herdará o campo name e o método eat().
  • Dog não enxerga o campo age nem o método secret() — eles são privados.

4. Restrições de herança em Java

Java é bastante rígida e tem suas próprias regras:

Apenas herança simples de classes: cada classe pode herdar de apenas uma outra classe. Já o número de herdeiros de uma classe pode ser ilimitado.

class Dog extends Animal { ... } // OK
class Dog extends Animal, Pet { ... } // Erro! Não é permitido

Herança múltipla de interfaces — é possível, mas isso é outro assunto e falaremos sobre ele mais adiante.

A classe Object — é a ancestral de todas as classes em Java. Mesmo que você não escreva explicitamente extends, sua classe ainda herda implicitamente de Object.

5. Exemplo prático

Vamos continuar construindo nosso aplicativo “zoológico”.

Etapa 1. Classe base Animal

class Animal {
    String name;

    void eat() {
        System.out.println(name + " come.");
    }
}

Etapa 2. Subclasse Cat

class Cat extends Animal {
    void meow() {
        System.out.println(name + " diz: Miau!");
    }
}

Etapa 3. Subclasse Dog

class Dog extends Animal {
    void bark() {
        System.out.println(name + " diz: Au!");
    }
}

Etapa 4. Usando as classes

public class Main {
    public static void main(String[] args) {
        Cat cat = new Cat();
        cat.name = "Murka";
        cat.eat();   // Murka come.
        cat.meow();  // Murka diz: Miau!

        Dog dog = new Dog();
        dog.name = "Sharik";
        dog.eat();   // Sharik come.
        dog.bark();  // Sharik diz: Au!
    }
}

O que obtivemos?

  • As classes Cat e Dog usam o campo comum name e o método eat() da classe base.
  • Cada classe adiciona seu comportamento único: meow() para o gato, bark() para o cachorro.
  • Se for preciso mudar a forma como os animais comem, basta alterar o método eat() na classe Animal — as mudanças serão aplicadas automaticamente a todos os herdeiros.

6. Dicas úteis

Visualização: hierarquia de classes

Podemos imaginar a hierarquia assim:

.        Animal
        /    \
     Cat     Dog
  • Animal — classe base, contém tudo o que é comum aos animais.
  • Cat e Dog — subclasses, adicionam características únicas.

Um pouco sobre construtores e herança

Construtores não são herdados. Se você não definir um construtor na subclasse, o Java adicionará automaticamente um construtor sem parâmetros (se ele existir na classe pai). Se a classe pai tiver apenas construtor com parâmetros, então na subclasse ele deve ser chamado explicitamente via super(...). Exemplo curto:

class Animal {
    String name;
    Animal(String name) {
        this.name = name;
    }
}

class Cat extends Animal {
    Cat(String name) {
        super(name); // chamamos o construtor do pai
    }
}

7. Erros comuns ao usar herança

Erro nº 1: Tentar herdar de várias classes ao mesmo tempo.
Em Java não é possível escrever class Cat extends Animal, Pet. Apenas um pai!

Erro nº 2: Esperar que campos e métodos privados fiquem acessíveis na subclasse.
Membros privados não são herdados (ou melhor, eles existem, mas não são acessíveis a partir da subclasse). Use protected se quiser permitir acesso aos herdeiros.

Erro nº 3: Esquecer de chamar o construtor do pai.
Se na classe base não houver construtor sem parâmetros e você não chamar explicitamente super(...), ocorrerá um erro de compilação.

Erro nº 4: Usar herança “apenas para economizar código”, e não por semântica.
Se não houver relação de “é um” (is-a) entre as classes, é melhor não usar herança. Por exemplo, “Pessoa” não deve herdar de “Automóvel”, mesmo que ambas tenham o campo speed.

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