11.6. Estrutura de Classes e Objetos em Java: Herança
A herança é um dos conceitos fundamentais da programação orientada a objetos (OOP) e, no Java, ela é uma parte crucial que permite uma estrutura de classes e objetos eficiente e poderosa. A herança permite que uma classe herde campos e métodos de outra classe, promovendo o reuso de código e a criação de uma hierarquia de classes relacionadas.
O que é Herança?
Herança é um mecanismo pelo qual uma nova classe, chamada de subclasse, pode adquirir as propriedades de uma classe já existente, chamada de superclasse. A herança facilita a modularidade e a organização do código, permitindo que os desenvolvedores criem classes mais especializadas a partir de classes mais gerais.
Como a Herança Funciona em Java
Em Java, a herança é realizada com a palavra-chave extends
. Quando uma classe é derivada de outra classe usando extends
, ela herda todos os membros públicos e protegidos (campos, métodos) da superclasse. Os membros privados da superclasse não são herdados diretamente, mas podem ser acessados por meio de métodos públicos ou protegidos.
class Animal {
String nome;
public void emitirSom() {
System.out.println("O animal faz um som.");
}
}
class Cachorro extends Animal {
public void emitirSom() {
System.out.println("O cachorro late: Au Au!");
}
}
No exemplo acima, a classe Cachorro
herda da classe Animal
. Isso significa que um objeto Cachorro
terá acesso ao campo nome
e poderá chamar o método emitirSom()
.
Sobrescrita de Métodos (Method Overriding)
Na herança, a subclasse tem a capacidade de sobrescrever os métodos da superclasse. Isso é feito para definir um comportamento específico na subclasse. No exemplo anterior, o método emitirSom()
é sobrescrito na classe Cachorro
para refletir o som específico que um cachorro faz.
Uso do super
A palavra-chave super
é usada para fazer referência direta ao objeto da superclasse. Ela pode ser usada para chamar o construtor da superclasse, bem como para acessar métodos que foram sobrescritos pela subclasse.
class Gato extends Animal {
public Gato() {
super.nome = "Gato";
}
public void emitirSom() {
super.emitirSom(); // Chama o método da superclasse
System.out.println("O gato mia: Miau!");
}
}
No exemplo acima, o construtor da classe Gato
atribui um valor ao campo nome
da superclasse Animal
. E o método emitirSom()
chama primeiro o método da superclasse antes de adicionar seu próprio comportamento.
Herança e Construtores
Em Java, os construtores não são herdados. No entanto, a subclasse pode chamar os construtores da superclasse usando a palavra-chave super
. Isso é geralmente feito na primeira linha do construtor da subclasse.
class Pássaro extends Animal {
public Pássaro() {
super(); // Chama o construtor da superclasse
// Outras inicializações
}
}
É importante notar que se a superclasse não tiver um construtor sem argumentos (um construtor padrão), a subclasse deverá chamar explicitamente um dos construtores disponíveis da superclasse.
Modificadores de Acesso e Herança
Os modificadores de acesso em Java definem como os membros de uma classe podem ser acessados. Na herança, esses modificadores determinam o que é herdado pela subclasse:
- Public: Os membros públicos são herdados pela subclasse e são acessíveis de qualquer outra classe.
- Protected: Os membros protegidos são herdados pela subclasse e são acessíveis dentro do mesmo pacote ou por subclasses em pacotes diferentes.
- Private: Os membros privados não são herdados pela subclasse, mas podem ser acessados indiretamente por meio de métodos públicos ou protegidos da superclasse.
Herança e Polimorfismo
Polimorfismo é outro conceito chave da OOP que permite que objetos de diferentes subclasses sejam tratados como objetos da superclasse. Isso é possível graças à herança e permite que o mesmo método seja utilizado em diferentes contextos, dependendo do tipo de objeto que o invoca.
Animal meuAnimal = new Cachorro();
meuAnimal.emitirSom(); // Saída: O cachorro late: Au Au!
No exemplo acima, mesmo que meuAnimal
seja do tipo Animal
, o método emitirSom()
que é chamado é o da classe Cachorro
, graças ao polimorfismo.
Considerações Finais Sobre Herança
Herança é uma ferramenta poderosa, mas deve ser usada com cuidado. O uso excessivo de herança pode levar a hierarquias de classes complexas e difíceis de manter. É importante projetar sistemas com herança apenas quando faz sentido conceitualmente, e não apenas para reutilizar código. Composição, onde uma classe contém outra classe, muitas vezes pode ser uma alternativa mais flexível à herança.
Em resumo, a herança em Java permite criar uma estrutura de classes e objetos eficiente, promovendo o reuso de código e a organização lógica. Ao entender e aplicar corretamente os conceitos de herança, sobrescrita de métodos, uso de super
, modificadores de acesso e polimorfismo, os desenvolvedores podem construir sistemas robustos e escaláveis.