13 Herança
Especializar comportamento sem criar hierarquias frágeis
13.1 Objetivos de aprendizagem
Ao concluir este capítulo, você deverá ser capaz de:
- reconhecer uma relação legítima de especialização;
- inicializar a superclasse com
super; - sobrescrever métodos com
@Override; - usar classes abstratas;
- justificar quando composição é preferível.
13.2 Relação é-um
Herança representa uma relação “é um”. Antes de usar extends, teste a frase “todo X é um Y” e confirme que a subclasse pode respeitar o contrato da superclasse.
abstract class MensagemBot {
private final String categoria;
protected MensagemBot(String categoria) {
this.categoria = categoria;
}
public String getCategoria() {
return categoria;
}
public abstract String texto();
}
final class Saudacao extends MensagemBot {
Saudacao() {
super("saudação");
}
@Override
public String texto() {
return "Olá! Vamos estudar Java?";
}
}
final class Dica extends MensagemBot {
Dica() {
super("dica");
}
@Override
public String texto() {
return "Mantenha métodos pequenos e testáveis.";
}
}
public class Capitulo12Heranca {
public static void main(String[] args) {
MensagemBot mensagem = new Dica();
System.out.println(mensagem.getCategoria());
System.out.println(mensagem.texto());
}
}A referência tem o tipo MensagemBot, mas o método executado pertence a Dica. Esse comportamento prepara o estudo de polimorfismo.
13.3 Construtores e super
Construtores não são herdados. A inicialização da superclasse ocorre antes da subclasse. Se a superclasse não tiver construtor sem parâmetros, a subclasse precisa chamar super(...).
Membros private continuam presentes no objeto, mas só são acessados pelos métodos da própria superclasse. Evite transformar atributos em protected apenas para facilitar acesso; prefira operações protegidas ou públicas que mantenham as invariantes.
13.4 Sobrescrita
@Override permite que o compilador confirme a intenção de sobrescrever. A assinatura deve ser compatível e a subclasse não deve enfraquecer o contrato esperado.
Sobrecarga e sobrescrita são diferentes:
- sobrecarga: mesmo nome, parâmetros diferentes, decisão em compilação;
- sobrescrita: mesma assinatura em uma subclasse, decisão em execução.
13.5 Classes abstratas e final
Uma classe abstrata representa um conceito incompleto e pode combinar estado, métodos concretos e métodos abstratos. Uma classe final bloqueia herança quando a extensão não foi planejada.
Não crie hierarquias profundas. Duas ou três camadas já exigem atenção; cadeias maiores tornam alterações e testes mais difíceis.
13.6 Quando preferir composição
Carrotem um motor: composição.Chatbottem um histórico: composição.Dicaé uma mensagem do bot: herança pode ser adequada.
Se o objetivo é apenas reutilizar algumas linhas, herança provavelmente é a ferramenta errada.
O exemplo completo está em examples/src/Capitulo12Heranca.java.
13.7 Prática verificável
Crie uma nova subclasse Aviso que devolva uma mensagem de atenção. Depois, responda:
- qual estado pertence à superclasse?
- qual comportamento foi sobrescrito?
- a substituição de
DicaporAvisomantém o programa válido? - seria melhor modelar esse caso com composição?
Use herança para representar substituição comportamental, não como mecanismo automático de reúso.