Soluções — Herança: DNA, Fragilidade e Template Method
Aula 8 — Programação Orientada a Objetos
Dica(Resposta) Teste 1 — Herança como Identidade (“É-UM”)
- ✔ Verdadeiro — É a distinção central do bloco: associação é uma referência externa entre objetos independentes; herança é incorporação física de estrutura, uma relação de identidade — o filho não só se relaciona com o pai, ele é uma especialização do pai.
- ✗ Falso — É o oposto do que a aula descreve: herdar não é “assinar um contrato” (isso é o papel das interfaces) — é incorporação física. Quando
Cartaoé instanciado, a Heap contém tanto os atributos definidos localmente quanto os herdados deMeioPagamentoBase. - ✗ Falso — Herança é incorporação física e acoplamento vitalício (o filho carrega a estrutura do pai); guardar uma referência a
Enderecoé apenas associação/composição, um acoplamento mais fraco e mais fácil de trocar — os dois tipos de relação não têm a mesma força, mesmo aparecendo na mesma classe. - ✔ Verdadeiro — É a “incorporação física” descrita na aula: ao instanciar
Cartao, a Heap aloca tanto o campo local (limite) quanto o campo herdado (idCobranca) — não existe uma versão “mais leve” da instância que omita o que veio do pai.
Dica(Resposta) Teste 2 — O Modificador
protected
- ✔ Verdadeiro — É a definição operacional de
protectedusada na aula: o estado fica acessível dentro da família de classes (pai e filhos), mas continua oculto para qualquer código externo à hierarquia. - ✗ Falso —
protectedainda vaza o estado para toda a linhagem de subclasses (“encapsulamento de linhagem”), enquantoprivatenão vaza para ninguém fora da própria classe — não são equivalentes; é exatamente essa diferença que motiva blindar atributos críticos comprivate. - ✔ Verdadeiro —
privatebloqueia o acesso até para subclasses; qualquer subclasse que dependia do acesso direto ao campoprotectedperde a compilação — é o custo de “blindar a base” mencionado na aula, e por isso a transição paraprivateexige, ao mesmo tempo, expor um método de acesso controlado. - ✔ Verdadeiro — É exatamente o exemplo de
alterarStatus()da aula: semfinal,Cartaopode sobrescrever o método e ignorar a checagem de invariante do pai, tratando a validação como uma mera “sugestão”.
Dica(Resposta) Teste 3 — O Problema da Classe Base Frágil
- ✔ Verdadeiro — Como a contagem duplicada vinha da chamada interna do pai a um método sobrescrito, remover essa chamada interna faz o
totalTransacoesdoCartao“corrigir-se” sozinho — sem que uma única linha doCartaotenha sido tocada, ilustrando como o filho está à mercê de decisões internas do pai que ele nem vê. - ✔ Verdadeiro —
super.processarLote()chamaprocessarPagamento()internamente; por polimorfismo/Late Binding, essa chamada é desviada para a versão sobrescrita emCartao, que incrementa o contador de novo — daí o resultado 6 em vez de 3. - ✗ Falso — É justamente o oposto — o compilador não enxerga esse tipo de dependência semântica entre métodos; o bug só se manifesta em runtime, ao observar o valor incorreto de
totalTransacoes, o que torna o Problema da Classe Base Frágil especialmente perigoso. - ✔ Verdadeiro — É a síntese do bloco: como essas regras não aparecem na assinatura dos métodos nem no sistema de tipos, nenhuma ferramenta automática avisa quando elas são violadas — só a leitura cuidadosa do código do pai revela o risco.
Dica(Resposta) Teste 4 — Herança por Conveniência vs. Especialização Legítima
- ✗ Falso — Precisar de um único método utilitário não estabelece uma relação “É-UM” nem exige tratamento polimórfico — é o caso clássico de herdar por conveniência; a solução correta é composição (guardar uma referência a
FormatadorNumerico) ou, em Java, um método utilitáriostatic. - ✗ Falso — É exatamente o exemplo de “herança por conveniência” dado na aula: o gerenciador usa uma lista, não é uma lista — não há relação “É-UM” real, só reaproveitamento de métodos prontos.
- ✗ Falso — Implementar o método exigido não basta — especialização legítima exige as duas condições simultâneas (compartilhar o DNA e precisar de tratamento polimórfico); se
RegistroDeAuditorianunca é tratado como umPagavelem lugar algum do sistema, falta a segunda condição, e a herança aqui é só reuso de estrutura disfarçado. - ✔ Verdadeiro — É a correção proposta na aula para o erro de
GerenciadorDeCobrancas extends ListaDeContatos: trocar a herança por uma referência privada à lista, guardando a relação de uso sem os riscos de vazamento de métodos e de identidade incoerente.
Dica(Resposta) Teste 5 — Invariantes Invisíveis
- ✗ Falso — Um comentário Javadoc não é verificado pelo compilador nem pela JVM — a dependência de ordem continua vivendo só na convenção/documentação, não na assinatura ou no tipo; ela só deixaria de ser “invisível” de fato se fosse imposta estruturalmente (por exemplo, com um Template Method
final). - ✗ Falso — É exatamente a armadilha de “semântica de retorno” descrita na aula: se o filho sobrescreve o método e passa a retornar
null, todo código do pai (ou de terceiros) que confiava na garantia de “nuncanull” quebra comNullPointerException, longe da causa real. - ✗ Falso — Mesmo que o filho atualize
status“corretamente” à primeira vista, ele pula qualquer lógica adicional que o pai executasse emsuper.alterarStatus()(validações, contadores, notificações) — é exatamente esse tipo de omissão que gera a “máquina de estado zumbi”: o objeto parece vivo e funcional, mas seu ciclo de vida lógico ficou incompleto. - ✗ Falso —
@Deprecatedé só um aviso informativo ao desenvolvedor (geralmente sinalizado pelo IDE); não é verificado pelo compilador como uma regra e não impõe ordem de chamada nenhuma — continua sendo, na prática, uma convenção que vive fora do sistema de tipos.
Dica(Resposta) Teste 6 — A Base como Guardiã
- ✔ Verdadeiro — É a primeira medida de “blindagem” descrita na aula:
protectedainda vaza para a família; sóprivategarante que nenhuma subclasse corrompa o atributo diretamente, forçando o acesso pelos métodos controlados do pai. - ✔ Verdadeiro — É a segunda medida de blindagem: travar com
finalo método de transição de estado impede que uma subclasse faça exatamente o queCartaofez no exemplo da fragilidade — sobrescrever e ignorar a checagem de invariante. - ✔ Verdadeiro — É o papel do gancho na base-guardiã: o filho implementa apenas o pedaço que exige conhecimento especializado (
executarProcessamento()), enquanto o restante do fluxo (validação, ordem dos passos) permanece protegido na base. - ✗ Falso — É o oposto do propósito da blindagem: ao tornar os atributos críticos
private, os métodos de transiçãofinale os detalhes técnicos ganchosabstract, a integridade do sistema passa a depender da base (um único ponto de controle), não do acerto individual de cada subclasse.
Dica(Resposta) Teste 7 — Classes Abstratas
- ✔ Verdadeiro — É a metáfora do chassi: rodas, bancos e suspensão (métodos concretos, como
validarValor()) já vêm prontos; só o “motor” (o métodoabstract) falta. - ✔ Verdadeiro — O compilador age como “inspetor de fábrica” e rejeita a instanciação de qualquer classe abstrata, completa ou não —
new MeioPagamentoBase(100.0)nem compila, mesmo que todos os métodos concretos existam. - ✗ Falso — É o oposto do que a aula defende: uma classe abstrata é um compromisso arquitetural — a “máquina semi-acabada” que força as subclasses a completar o “motor” — não uma limitação técnica arbitrária.
- ✔ Verdadeiro — É a aplicação direta da metáfora do chassi ao elemento sintático
abstract: o método sem corpo é exatamente o “buraco” que cada subclasse concreta precisa preencher com seu próprio motor.
Dica(Resposta) Teste 8 — Herança de Estado vs. Comportamento
- ✔ Verdadeiro — Como interfaces herdam só comportamento (a assinatura do método), o filho é livre para decidir como implementá-lo — inclusive sem guardar estado algum; isso é exatamente o que a aula descreve como a “fluidez” da herança de comportamento, em contraste com a rigidez da herança de estado.
- ✗ Falso — Não existe, em Java, uma forma de uma subclasse “recusar” um campo herdado — toda instância de
PixcarregalogsInternosna Heap, use ou não; herdar estado é compulsório, diferente da liberdade que existe ao herdar comportamento via interface. - ✗ Falso — É a mesma conclusão do item anterior: herança de estado é alocação compulsória; não há palavra-chave ou anotação padrão em Java que permita a um filho “deserdar” um campo do pai.
- ✔ Verdadeiro — Se
idCobrancamudar deStringparaUUID, toda subclasse que o acessa diretamente (viaprotected) precisa ser revista e ajustada — é o custo de longo prazo da herança de estado mencionado na aula.
Dica(Resposta) Teste 9 — Template Method: o Esqueleto
- ✔ Verdadeiro — É a própria assinatura de
realizarPagamento()no exemplo da aula:finalimpede que qualquer subclasse sobrescreva o método e altere a ordem validação → especialização → log. - ✗ Falso — Uma classe concreta em Java é obrigada a implementar todos os métodos abstratos herdados; deixar um método-gancho sem implementação impede a compilação (a menos que a própria subclasse também seja declarada
abstract) — o compilador garante que nenhum gancho fique “aberto”. - ✔ Verdadeiro — É exatamente o risco de não travar
realizarPagamento()comfinal: sem essa trava, nada impede umPixde esquecer o log, ou umBoletode pular a validação, cada um implementando sua própria ordem. - ✗ Falso — É o oposto: no Template Method é o pai quem decide a sequência (fixada pelo
final), e o filho só preenche a lacuna do gancho — é justamente essa centralização que aumenta a previsibilidade.
Dica(Resposta) Teste 10 — Inversão de Controle e o Princípio de Hollywood
- ✔ Verdadeiro — É a mesma Inversão de Controle: o framework (equivalente ao “pai”) controla o fluxo e decide quando chamar o código do desenvolvedor (
setUp()), em vez do desenvolvedor chamar o framework — “não nos ligue, nós ligamos para você” se aplica a qualquer arquitetura onde o controle do fluxo principal foi invertido, não só ao Template Method dentro de uma única hierarquia de classes. - ✗ Falso — Delegar uma tarefa pontual para uma função de biblioteca não é Inversão de Controle — o script continua no comando, decidindo quando e como chamar a biblioteca; IoC exige o contrário: o framework/base retém o fluxo principal e decide quando chamar o código do desenvolvedor, como o Template Method faz com o gancho.
- ✗ Falso — É o inverso: é o pai quem retém o controle do fluxo (
realizarPagamento()éfinale vive na base) e decide, num ponto fixo dessa sequência, quando desviar para o gancho do filho — o filho nunca decide “voltar” para o pai. - ✔ Verdadeiro — O padrão continuar sintaticamente correto (
final+abstract) não impede que o esqueleto seja mal projetado na prática; se os passos fixos forem excessivos ou inadequados para alguns dos filhos, o Template Method se torna uma camisa de força mesmo estando implementado “certo” tecnicamente — o risco é de design, não de sintaxe.
Dica(Resposta) Teste 11 — Vantagens e Riscos do Template Method
- ✔ Verdadeiro — É a garantia de previsibilidade do padrão: como o esqueleto é
finale vive na classe base,registrarLog()roda para toda subclasse, presente ou futura, independentemente de o desenvolvedor da subclasse conhecer ou lembrar dessa regra — a garantia está na estrutura, não na disciplina do programador. - ✔ Verdadeiro — É exatamente o custo de não usar Template Method: sem um esqueleto centralizado na base, cada subclasse duplica a lógica de log, e uma mudança na regra precisa ser replicada em cada uma — o ganho de manutenibilidade do padrão vem de centralizar essa lógica compartilhada num único lugar.
- ✗ Falso — É o oposto — a “limitação do erro” listada como vantagem na aula é justamente que o desenvolvedor da subclasse só precisa conhecer o gancho que vai implementar, sem precisar entender ou tocar no fluxo geral controlado pela base.
- ✔ Verdadeiro — É a definição de IoC aplicada ao Template Method — o “Princípio de Hollywood” resumido na aula: a base retém o fluxo e chama o gancho do filho no momento certo, nunca o contrário.
Dica(Resposta) Teste 12 — Síntese: Herança como Ferramenta de Especialização
- ✔ Verdadeiro — É a síntese da distinção entre herança por conveniência e especialização legítima que atravessa a aula inteira: reaproveitar código sozinho nunca justifica
extends. - ✗ Falso — Compartilhar o DNA é só uma das duas condições; renomear um método sem adicionar valor nem justificar tratamento polimórfico diferenciado é o próprio “objeto zumbi” descrito na aula — a subclasse existe, mas não agrega nada à taxonomia, só a polui.
- ✔ Verdadeiro — É a conexão entre os dois blocos centrais da aula: as três medidas de blindagem existem precisamente para impedir os tipos de violação silenciosa de invariante que caracterizam o Problema da Classe Base Frágil.
- ✗ Falso — É o oposto do que a aula estabelece desde a abertura: a herança é “o acoplamento mais forte da Orientação a Objetos”, justamente por incorporar estrutura física, e não apenas guardar uma referência externa como a composição.