Visão Geral
A herança de classes permite construir uma nova classe com base em uma classe existente.
- A nova classe é chamada de subclasse (ou classe filha), e a classe existente é a superclasse (ou classe pai).
- A subclasse herda automaticamente todos os membros (atributos e métodos) que são acessíveis da superclasse.
Como Implementar Herança?
Para declarar que uma classe herdda de outra, utiliza-se a palavra-chave extends.
Vamoss criar uma classe Pessoa:
public class Pessoa {
private char genero;
public Pessoa() {
System.out.println("Construtor sem parâmetros de Pessoa executado");
}
public char getGenero() {
return genero;
}
public void setGenero(char genero) {
this.genero = genero;
}
public void dormir() {
System.out.println("Precisa dormir...");
}
}
Criando a classe Estudante que herda de Pessoa:
public class Estudante extends Pessoa {
private String nome;
int idade;
public Estudante() {}
public Estudante(String nome) {
this.nome = nome;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public void apresentar() {
System.out.println("Meu gênero é " + getGenero());
}
}
Código de teste (main):
public static void main(String[] args) {
Estudante e1 = new Estudante("Melancia");
e1.idade = 10;
// e1.genero = 'M'; // Erro: genero é privado e não herdado
e1.setGenero('M');
e1.apresentar();
e1.dormir();
}
Resultado:
Construtor sem parâmetros de Pessoa executado
Meu gênero é M
Precisa dormir...
Observações:
- A classe
Estudantenão declarougeneronemdormir(), mas conseguiu acessá-los (excetogeneropor ser privado). - O atributo
generoéprivate, portento não é herdado. - Quando um objeto
Estudanteé criado, o construtor da superclassePessoaé chamado automaticamente (antes do construtor da subclasse). Internamente, a JVM aloca espaço para o objeto da superclasse e depois para a subclasse, com uma referênciasuperligando os dois.
Herança e Modificadores de Acesso
A tabela a seguir mostra a acessibilidade dos membros:
| Modificador | Mesma classe | Mesmo pacote | Subclasse | Global |
|---|---|---|---|---|
| public | ✓ | ✓ | ✓ | ✓ |
| protected | ✓ | ✓ | ✓ | |
| (default) | ✓ | ✓ | ||
| private | ✓ |
Apenas membros com private não são herdados. Membros com modificador default (sem modificador) são acessíveis dentro do mesmo pacote — no exemplo, Pessoa e Estudante estão no mesmo pacote, por isso o atributo idade (com default) é acessível.
Herança e Relações entre Classes
Algumas regras importantes:
- Herança simples: Java não permite herança múltipla de classes (uma classe só pode ter uma superclasse direta).
- Uma superclasse pode ter várias subclasses.
- Herança multinível: É permitido que uma classe filha se torne pai de outra.
- Métodos podem ser sobrescritos (override): A subclasse pode redefinir um método da superclasse, desde que mantenha o mesmo nome, parâmetros e tipo de retorno.
Exemplo de sobrescrita em Estudante:
@Override
public void dormir() {
System.out.println(nome + " precisa dormir...");
}
Testando:
public static void main(String[] args) {
Estudante e1 = new Estudante("Melancia");
e1.dormir();
}
Resultado:
Construtor sem parâmetros de Pessoa executado
Melancia precisa dormir...
Regra importante: Um método sobrescrito na subclasse não pode ter um modificador de acesso mais restritivo do que o método original. Se o método na superclasse é public, a subclasse não pode torná-lo private (causaria erro de compilação). Por outro lado, se o método na superclasse for private, ele não é herdado, portanto não há sobrescrita — a subclasse pode declarar um método com o mesmo nome e um modificador mais permissivo sem problemas.