24 Herança
Reuso com especialização: quando usar e quando evitar.
Todo bom programador evolui mais rápido quando entende por que um tema importa antes de memorizar sintaxe. Neste capítulo, vamos conectar conceito, contexto e prática para transformar teoria em habilidade real.
- Ideia central: o que este tema resolve em projetos Java.
- Linguagem técnica: quais termos você precisa dominar.
- Aplicação prática: como usar no código do dia a dia.
- Armadilhas comuns: erros frequentes de iniciantes.
- Critério de domínio: como saber se você aprendeu de verdade.
24.1 Estudo de caso guiado
Imagine uma pequena plataforma acadêmica para cadastro de alunos, notas e turmas. A cada aula, evoluímos essa plataforma com um novo recurso. Neste capítulo, o foco é aplicar o tema para deixar o sistema mais claro, seguro e fácil de manter.
24.2 Exemplo comentado em Java
class Veiculo {
void mover() { System.out.println("Movendo"); }
}
class Carro extends Veiculo {
@Override
void mover() { System.out.println("Carro em movimento"); }
}24.3 Fundamentos tecnicos de heranca
Em Java, heranca representa uma relacao de especializacao do tipo is-a (“eh um”). Isso significa que uma classe derivada herda estado e comportamento da classe base, mas tambem pode refinar comportamentos para atender regras mais especificas do dominio.
Quando voce usa extends, a subclasse passa a ter acesso aos membros public e protected da superclasse, respeitando encapsulamento. Membros private continuam existindo no objeto, mas so podem ser acessados indiretamente por metodos da propria superclasse.
Uma forma pratica de validar se a heranca faz sentido e testar a frase: “Todo X eh um Y”. Por exemplo, Carro eh um Veiculo, mas Motor nao eh um Veiculo; nesse caso, composicao geralmente descreve melhor a modelagem.
24.4 Construtores e palavra-chave super
Construtores nao sao herdados, mas a inicializacao da superclasse sempre acontece antes da inicializacao da subclasse. Por isso, o uso de super(...) e essencial quando a classe base exige dados obrigatorios.
class Pessoa {
protected String nome;
Pessoa(String nome) {
this.nome = nome;
}
}
class Aluno extends Pessoa {
private String matricula;
Aluno(String nome, String matricula) {
super(nome); // inicializa a parte Pessoa
this.matricula = matricula;
}
}Quando super(...) nao e chamado explicitamente, o compilador tenta inserir super() automaticamente. Se a superclasse nao tiver construtor sem parametros, o codigo nao compila.
24.5 Sobrescrita, polimorfismo e @Override
Sobrescrita (override) ocorre quando a subclasse redefine um metodo herdado com a mesma assinatura. Esse recurso permite comportamento polimorfico: uma referencia do tipo da superclasse pode executar a implementacao da subclasse em tempo de execucao.
class Funcionario {
double calcularBonus() { return 500.0; }
}
class Gerente extends Funcionario {
@Override
double calcularBonus() { return 1200.0; }
}O uso de @Override e uma boa pratica porque o compilador valida sua intencao. Se houver erro de assinatura, voce recebe aviso cedo e evita bugs silenciosos.
24.6 Heranca e classes abstratas
Quando uma classe representa um conceito generico demais para ser instanciado diretamente, use abstract. Ela pode definir metodos concretos e metodos abstratos que obrigam subclasses a fornecer implementacao.
abstract class Forma {
abstract double area();
void exibirTipo() {
System.out.println("Forma geometrica");
}
}
class Retangulo extends Forma {
private double base;
private double altura;
Retangulo(double base, double altura) {
this.base = base;
this.altura = altura;
}
@Override
double area() {
return base * altura;
}
}Esse desenho melhora extensibilidade porque define um contrato comum e reduz duplicacao de regras compartilhadas.
24.7 Limites: final, acoplamento e profundidade de hierarquia
Metodos final nao podem ser sobrescritos. Classes final nao podem ser herdadas. Esse recurso e util para proteger invariantes importantes e evitar extensoes indevidas.
Tambem e importante evitar hierarquias profundas demais. Quanto maior a cadeia de heranca, maior tende a ser o acoplamento e mais dificil fica entender efeitos colaterais de uma mudanca. Em nivel introdutorio, prefira hierarquias curtas, nomes claros e regras bem localizadas.
24.8 Quando preferir composicao em vez de heranca
Heranca e poderosa, mas nao e a unica forma de reuso. Em muitos casos, composicao oferece mais flexibilidade e menor risco de acoplamento rigido.
Exemplo mental rapido:
- Heranca:
Carro extends Veiculo(relacao is-a). - Composicao:
Carrotem umMotor(relacao has-a).
Se a relacao principal for “tem um”, composicao costuma ser a decisao mais saudavel para evolucao futura do sistema.
24.9 Diagnostico de aprendizado tecnico
Para verificar se voce domina heranca com criterio, teste sua capacidade de:
- Identificar se um problema pede heranca ou composicao.
- Projetar superclasse com responsabilidade enxuta e coesa.
- Usar
super(...)corretamente em cenarios com construtores obrigatorios. - Aplicar sobrescrita com
@Overridesem quebrar contrato de comportamento. - Argumentar por que uma hierarquia precisa (ou nao) ser abstrata.
24.10 Erros clássicos e como evitar
- Copiar código sem entender a intenção de cada linha.
- Ignorar nomes claros para classes, métodos e variáveis.
- Pular testes curtos após cada pequena alteração.
- Tentar otimizar antes de ter uma versão correta.
24.11 Checklist de domínio
24.12 Trilha de prática (20-30 min)
- Reescreva o exemplo em um arquivo novo.
- Altere duas regras do problema e ajuste o código.
- Adicione uma validação extra.
- Execute e registre o resultado esperado.
24.13 Fechamento
Ao finalizar este capítulo, você não deve apenas reconhecer a sintaxe: deve conseguir tomar decisões melhores de implementação. Esse é o passo que diferencia leitura passiva de aprendizado de verdade.
Neste capitulo, o estudo de heranca em Java se torna realmente valioso quando voce deixa de enxergar o conteudo como uma lista de regras isoladas e passa a observar como cada decisao tecnica influencia a qualidade do programa, a facilidade de manutencao e a capacidade de adaptar a solucao sem quebrar o que ja estava funcionando, especialmente em atividades progressivas que simulam situacoes de projeto real.
Para consolidar o aprendizado com profundidade, vale estruturar sua pratica em uma sequencia objetiva na qual voce revisa o conceito principal, implementa um exemplo pequeno e legivel e, logo em seguida, analisa de maneira critica se houve melhoria concreta em reuso orientado a dominio, super e construtores e limites da generalizacao, porque esse ciclo consciente transforma estudo passivo em desenvolvimento de criterio tecnico.
Quando esse processo se repete ao longo das semanas, voce comeca a perceber que sua evolucao nao depende de decorar respostas prontas, mas sim de interpretar problemas com mais maturidade, justificar escolhas com argumentos claros e construir solucoes cada vez mais consistentes, o que representa exatamente a transicao de iniciante para praticante autonomo dentro da trilha de Java.