A herança é um dos conceitos fundamentais da Programação Orientada a Objetos (POO). Em Java, ela permite que uma classe aproveite características e comportamentos de outra classe, promovendo reutilização de código, organização e manutenção mais simples dos sistemas.
Além disso, a herança ajuda a reduzir a duplicação de código, tornando o desenvolvimento mais eficiente. Por esse motivo, ela é amplamente utilizada em aplicações de todos os tamanhos.
Neste artigo, você aprenderá o que é herança em Java, como ela funciona e verá exemplos práticos para consolidar o aprendizado.
O que é Herança?
Herança é um mecanismo que permite que uma classe herde atributos e métodos de outra classe.
A classe que fornece as características é chamada de superclasse (ou classe pai). Por outro lado, a classe que recebe essas características é chamada de subclasse (ou classe filha).
Em Java, utilizamos a palavra-chave extends para indicar que uma classe está herdando de outra.
Observe a estrutura básica:
public class Animal {
String nome;
public void dormir() {
System.out.println("O animal está dormindo.");
}
}
public class Cachorro extends Animal {
}
Nesse exemplo, a classe Cachorro herda automaticamente o atributo nome e o método dormir() da classe Animal.
Consequentemente, não precisamos recriar esses elementos na nova classe.
Por que Utilizar Herança?
A herança oferece diversas vantagens. Entre elas, destacam-se:
- Reutilização de código;
- Menor duplicação de lógica;
- Melhor organização do projeto;
- Facilidade de manutenção;
- Relacionamento natural entre classes.
Além disso, ela permite representar situações do mundo real de forma mais intuitiva.
Por exemplo, um cachorro é um animal. Portanto, faz sentido que a classe Cachorro herde características da classe Animal.
Exemplo 1: Animal e Cachorro
Vamos analisar um exemplo mais completo.
public class Animal {
String nome;
public void comer() {
System.out.println("O animal está comendo.");
}
}
Agora criamos uma classe que herda de Animal:
public class Cachorro extends Animal {
}
E utilizamos a classe:
public class Main {
public static void main(String[] args) {
Cachorro cachorro = new Cachorro();
cachorro.nome = "Rex";
cachorro.comer();
System.out.println(cachorro.nome);
}
}
Saída:
O animal está comendo.
Rex
Observe que a classe Cachorro não possui nem o atributo nome nem o método comer(). Entretanto, ela consegue utilizá-los porque os herdou da classe Animal.
Exemplo 2: Veículo e Carro
Outro exemplo bastante comum envolve veículos.
Primeiramente, criamos uma classe genérica:
public class Veiculo {
String marca;
public void ligar() {
System.out.println("Veículo ligado.");
}
}
Em seguida, criamos a classe Carro:
public class Carro extends Veiculo {
}
Agora podemos utilizar os recursos herdados:
public class Main {
public static void main(String[] args) {
Carro carro = new Carro();
carro.marca = "Toyota";
carro.ligar();
System.out.println(carro.marca);
}
}
Nesse caso, o carro passa a possuir todas as características definidas na classe Veiculo.
Dessa forma, qualquer alteração na classe pai poderá beneficiar todas as classes filhas.
Exemplo 3: Funcionário e Gerente
Em sistemas corporativos, a herança é extremamente útil.
Considere a seguinte classe:
public class Funcionario {
String nome;
double salario;
public void exibirDados() {
System.out.println(nome + " - R$ " + salario);
}
}
Agora criamos uma especialização:
public class Gerente extends Funcionario {
}
Utilização:
public class Main {
public static void main(String[] args) {
Gerente gerente = new Gerente();
gerente.nome = "Carlos";
gerente.salario = 8500.00;
gerente.exibirDados();
}
}
Resultado:
Carlos - R$ 8500.0
Perceba que o gerente é um funcionário. Portanto, ele pode aproveitar todos os atributos e métodos já existentes na classe base.
A Palavra-Chave extends
Em Java, a herança é declarada por meio da palavra-chave extends.
Exemplo:
public class Filho extends Pai {
}
A partir desse momento, a classe Filho passa a herdar os membros acessíveis da classe Pai.
Além disso, ela poderá utilizar esses recursos como se tivessem sido declarados diretamente nela.
Limitações da Herança em Java
Embora a herança seja muito poderosa, existem algumas regras importantes.
Java não permite herança múltipla de classes
O código abaixo não é válido:
public class MinhaClasse extends ClasseA, ClasseB {
}
Isso acontece porque o Java foi projetado para evitar ambiguidades que poderiam surgir quando duas classes possuem métodos com o mesmo nome.
Portanto, uma classe só pode herdar diretamente de uma única classe.
Nem tudo pode ser herdado
Dependendo do modificador de acesso utilizado, alguns atributos e métodos podem não estar disponíveis para as subclasses.
Por esse motivo, é importante compreender também conceitos como encapsulamento e modificadores de acesso, que normalmente são estudados junto com herança.
Exemplo: atributo private não pode ser acessado diretamente pela classe filha
public class Pessoa {
private String cpf;
public void setCpf(String cpf) {
this.cpf = cpf;
}
public String getCpf() {
return cpf;
}
}
Classe filha:
public class Cliente extends Pessoa {
public void mostrarCpf() {
// ERRO DE COMPILAÇÃO
// System.out.println(cpf);
}
}
O atributo cpf existe dentro da classe Pessoa, porém ele é private. Portanto, a classe Cliente não consegue acessá-lo diretamente.
A forma correta seria utilizar os métodos públicos:
public class Cliente extends Pessoa {
public void mostrarCpf() {
System.out.println(getCpf());
}
}
Exemplo: método private não é herdado
Classe pai:
public class Animal {
private void respirar() {
System.out.println("Respirando...");
}
}
Classe filha:
public class Cachorro extends Animal {
public void teste() {
// ERRO DE COMPILAÇÃO
// respirar();
}
}
Como o método foi declarado como private, ele pertence exclusivamente à classe Animal.
Quando Utilizar Herança?
A herança deve ser utilizada quando existe uma relação clara do tipo:
“é um”
Por exemplo:
- Cachorro é um Animal;
- Carro é um Veículo;
- Gerente é um Funcionário.
Por outro lado, se essa relação não existir naturalmente, talvez a herança não seja a melhor escolha.
Nesses casos, outras técnicas de modelagem podem ser mais adequadas.
Conclusão
A herança em Java é um recurso fundamental da Programação Orientada a Objetos. Ela permite que classes reutilizem atributos e métodos já existentes, reduzindo a duplicação de código e tornando os projetos mais organizados.
Além disso, a herança ajuda a representar relacionamentos do mundo real de forma intuitiva e estruturada.
Neste artigo, vimos o conceito de herança, entendemos o papel das classes pai e filha, conhecemos a palavra-chave extends e analisamos três exemplos práticos.
No próximo passo, você poderá aprofundar seus conhecimentos estudando sobrescrita de métodos e polimorfismo, conceitos que trabalham em conjunto com a herança para tornar suas aplicações Java ainda mais flexíveis e poderosas.
