
Passo 1 de 7
Criar uma especialização por herança simples
Defina uma subclasse de Tarefa e reconheça os comportamentos que ela recebe da classe base sem copiar implementações.
Trilha de aprendizado · Nível 7 · Tutorial 5
Criar especializações por herança simples, sobrescrever métodos e estender comportamentos com super, escolhendo herança apenas quando a relação entre os tipos a justificar.
Criar uma especialização por herança simples
Defina uma subclasse de Tarefa e reconheça os comportamentos que ela recebe da classe base sem copiar implementações. 4 min
Sobrescrever um método
Defina na subclasse um método de mesmo nome para substituir o comportamento herdado. 3 min
Estender um comportamento com super
Use super() para aproveitar a descrição produzida pela classe base e acrescentar uma informação específica da subclasse, sem duplicar a lógica comum. 3 min
Inicializar a subclasse com super().__init__
Adicione a prioridade à subclasse sem perder a inicialização e a validação realizadas por Tarefa. 4 min
Preservar o que a classe base garante
Diagnostique inicializadores e sobrescritas que quebram regras, retornos ou operações já oferecidas pela classe base. 3 min
Escolher entre herança e composição
Use o significado dos tipos e suas responsabilidades para decidir entre especialização por herança e colaboração por composição. 2 min
Aplicar e revisar a especialização completa
Implemente TarefaPrioritaria em um script único, execute verificações manuais e compare sua implementação com uma solução que preserva as regras da classe base. 5 min

Passo 1 de 7
Defina uma subclasse de Tarefa e reconheça os comportamentos que ela recebe da classe base sem copiar implementações.
Uma TarefaPrioritaria continua sendo uma Tarefa, mas representa um caso mais específico. Essa relação justifica usar herança: a subclasse pode aproveitar o estado e os comportamentos definidos pela classe base.
A herança não deve ser escolhida apenas porque duas classes têm código parecido. A pergunta principal é: o novo tipo realmente é uma especialização do tipo existente? Neste caso, sim: toda tarefa prioritária ainda pode ser descrita e concluída como uma tarefa.
A seta representa a relação de especialização. Os comportamentos definidos em Tarefa ficam disponíveis em TarefaPrioritaria.

TarefaPrioritaria é um tipo mais específico de Tarefa e aproveita seus comportamentos.
Na definição da subclasse, o nome entre parênteses indica a classe base: class TarefaPrioritaria(Tarefa):.
Como a subclasse ainda não precisa acrescentar nada, usamos pass. Mesmo com o corpo vazio, ela pode usar __init__, descrever e concluir sem que essas implementações sejam copiadas para seu corpo.
Execute este script no seu computador e observe que a instância da subclasse usa os métodos definidos em Tarefa.
class Tarefa:
def __init__(self, titulo):
if not titulo.strip():
raise ValueError("O título não pode ficar vazio.")
self.titulo = titulo
self.concluida = False
def concluir(self):
self.concluida = True
def descrever(self):
estado = "concluída" if self.concluida else "pendente"
return f"{self.titulo} — {estado}"
class TarefaPrioritaria(Tarefa):
pass
prioritaria = TarefaPrioritaria("Corrigir falha crítica")
print(prioritaria.descrever())
prioritaria.concluir()
print(prioritaria.descrever())
# Saída esperada:
# Corrigir falha crítica — pendente
# Corrigir falha crítica — concluídaDica
Como TarefaPrioritaria não define um __init__, a criação do objeto usa o inicializador disponível em Tarefa. Por isso, titulo e concluida são inicializados e a validação de título não vazio continua valendo.
Quando um método é solicitado em uma instância de TarefaPrioritaria, a busca começa na subclasse. Como ela não define os métodos do exemplo, a busca segue para Tarefa.
Assim, a subclasse disponibiliza os comportamentos herdados sem duplicar suas implementações.
Relacione cada elemento à explicação correta.
Toque em um item e depois no par correspondente.

Passo 2 de 7
Defina na subclasse um método de mesmo nome para substituir o comportamento herdado.
Uma subclasse sobrescreve um método quando define um método com o mesmo nome daquele existente na classe base. Ao chamar descrever() em uma instância de TarefaPrioritaria, Python encontra primeiro a implementação da subclasse e usa somente ela.
A subclasse herda a inicialização e os demais métodos, mas fornece outra implementação de descrever.
class Tarefa:
def __init__(self, titulo):
self.titulo = titulo
self.concluida = False
def concluir(self):
self.concluida = True
def descrever(self):
status = "concluída" if self.concluida else "pendente"
return f"{self.titulo} [{status}]"
class TarefaPrioritaria(Tarefa):
def descrever(self):
return f"[PRIORITÁRIA] {self.titulo}"
Cada instância usa a primeira implementação de descrever encontrada a partir de sua própria classe.
A sobrescrita vale para instâncias da subclasse. Uma instância criada diretamente como Tarefa continua usando o método original. Além disso, chamar o método sobrescrito não executa automaticamente a implementação da classe base.
Considerando as classes da tela anterior, observe que cada chamada produz apenas um texto.
comum = Tarefa("Revisar relatório")
urgente = TarefaPrioritaria("Corrigir falha crítica")
print(comum.descrever())
print(urgente.descrever())
# Saída:
# Revisar relatório [pendente]
# [PRIORITÁRIA] Corrigir falha críticaComplete o nome que faz a subclasse substituir a descrição herdada:
class TarefaPrioritaria(Tarefa):
def ____ (self):
return f"[PRIORITÁRIA] {self.titulo}"
Com as classes apresentadas, qual saída será produzida?
print(Tarefa("Enviar proposta").descrever())
print(TarefaPrioritaria("Responder cliente").descrever())

Passo 3 de 7
Use super() para aproveitar a descrição produzida pela classe base e acrescentar uma informação específica da subclasse, sem duplicar a lógica comum.
Uma sobrescrita pode substituir completamente o método herdado ou estendê-lo. Para estender descrever, a subclasse chama super().descrever(), aproveita o texto básico retornado e acrescenta apenas a informação específica.
Neste exemplo de herança simples, super() dá acesso à implementação seguinte da hierarquia: Tarefa.descrever.

A chamada entra na sobrescrita, consulta a implementação da classe base e retorna à subclasse para completar o resultado.
Execute este script no seu computador e observe que a subclasse reutiliza a montagem da descrição básica.
class Tarefa:
def __init__(self, titulo):
if not titulo.strip():
raise ValueError("O título não pode ficar vazio.")
self.titulo = titulo
self.concluida = False
def descrever(self):
estado = "concluída" if self.concluida else "pendente"
return f"{self.titulo} — {estado}"
class TarefaPrioritaria(Tarefa):
def descrever(self):
descricao_base = super().descrever()
return f"{descricao_base} [PRIORITÁRIA]"
tarefa = TarefaPrioritaria("Revisar orçamento")
print(tarefa.descrever())
# Resultado esperado:
# Revisar orçamento — pendente [PRIORITÁRIA]Dica
super().descrever() não cria outra Tarefa. O método da classe base é executado sobre a mesma instância de TarefaPrioritaria. Também não se fornece self explicitamente: a vinculação da instância ocorre na chamada com super().
A classe base continua responsável por montar título e estado. A subclasse guarda o retorno em descricao_base e acrescenta somente [PRIORITÁRIA]. Se o formato básico mudar em Tarefa.descrever, a especialização continuará aproveitando essa implementação, em vez de manter uma cópia separada.
Coloque os acontecimentos na ordem em que ocorrem ao executar tarefa.descrever().
Explique por que super().descrever() é mais adequado do que reconstruir título e estado dentro de TarefaPrioritaria.descrever.
Escreva pelo menos 60 caracteres (0/60).

Passo 4 de 7
Adicione a prioridade à subclasse sem perder a inicialização e a validação realizadas por Tarefa.
Ao definir um __init__ em TarefaPrioritaria, a subclasse passa a controlar sua inicialização. Como ela ainda depende da parte comum de Tarefa, deve chamar super().__init__(titulo).
A classe base valida e armazena o título, além de criar o estado de conclusão. Depois, a subclasse valida e armazena a prioridade. Não há cópia de atributos de outro objeto: cada atributo surge quando esses inicializadores são executados sobre a mesma instância.
Execute este código em um script Python para observar a divisão de responsabilidades.
class Tarefa:
def __init__(self, titulo):
if not isinstance(titulo, str) or not titulo.strip():
raise ValueError("titulo deve ser um texto não vazio")
self.titulo = titulo
self.concluida = False
def concluir(self):
self.concluida = True
def descrever(self):
estado = "concluída" if self.concluida else "pendente"
return f"{self.titulo} — {estado}"
class TarefaPrioritaria(Tarefa):
def __init__(self, titulo, prioridade):
super().__init__(titulo)
if type(prioridade) is not int:
raise TypeError("prioridade deve ser um número inteiro")
if not 1 <= prioridade <= 3:
raise ValueError("prioridade deve estar entre 1 e 3")
self.prioridade = prioridade
def descrever(self):
descricao_basica = super().descrever()
return f"{descricao_basica} | Prioridade: {self.prioridade}"
tarefa = TarefaPrioritaria("Revisar relatório", 2)
print(tarefa.descrever())
# Resultado esperado:
# Revisar relatório — pendente | Prioridade: 2A criação começa em TarefaPrioritaria.__init__. A chamada a super().__init__(titulo) executa o inicializador de Tarefa sobre a mesma instância; por isso, não se fornece self explicitamente. Quando essa chamada termina, a subclasse continua e acrescenta prioridade.
O esquema separa a parte inicializada pela classe base da parte acrescentada pela subclasse.

Primeiro surgem titulo e concluida; depois, prioridade é adicionada à mesma instância.
Dica
Se a inicialização herdada já fornece todo o estado necessário, não defina outro __init__ na subclasse. Nesse caso, o inicializador da classe base pode ser usado diretamente, como ocorreu antes de adicionarmos a prioridade.
Complete a linha que mantém a inicialização de titulo e concluida fornecida por Tarefa:
class TarefaPrioritaria(Tarefa):
def init(self, titulo, prioridade):
__
self.prioridade = prioridade
Considere TarefaPrioritaria("Revisar relatório", 2). Explique:
__init__ da subclasse se ela não precisasse acrescentar estado?Escreva pelo menos 80 caracteres (0/80).

Passo 5 de 7
Diagnostique inicializadores e sobrescritas que quebram regras, retornos ou operações já oferecidas pela classe base.
Uma TarefaPrioritaria continua sendo uma especialização de Tarefa. Por isso, deve preservar as expectativas básicas já estabelecidas:
concluir() deve continuar funcionando;descrever() deve poder ser chamado sem novos argumentos obrigatórios;descrever() deve continuar retornando um texto com as informações básicas da tarefa.A subclasse pode acrescentar estado e comportamento, mas não deve deixar o objeto incompleto nem mudar o significado básico dessas operações.

À esquerda, a especialização mantém estado, validação e operações da base. À direita, conexões ausentes representam atributos, retornos e chamadas quebrados.
Dica
Ao revisar uma sobrescrita, compare a chamada, o retorno, o significado e os efeitos do método com o comportamento da classe base. Acrescentar informações é aceitável; exigir uma chamada incompatível ou eliminar um retorno esperado é um sinal de problema.
Leia o código e observe que cada subclasse compromete garantias diferentes de Tarefa.
class Tarefa:
def __init__(self, titulo):
if not titulo.strip():
raise ValueError("O título não pode ser vazio")
self.titulo = titulo
self.concluida = False
def concluir(self):
self.concluida = True
def descrever(self):
estado = "concluída" if self.concluida else "pendente"
return f"{self.titulo} — {estado}"
class TarefaComInicializacaoIncompleta(Tarefa):
def __init__(self, titulo, prioridade):
self.prioridade = prioridade
class TarefaComDescricaoIncompativel(Tarefa):
def descrever(self, prefixo):
print(f"{prefixo}: {self.titulo}")
incompleta = TarefaComInicializacaoIncompleta("Revisar relatório", 1)
# incompleta.descrever() tenta acessar atributos que não foram criados.
incompativel = TarefaComDescricaoIncompativel("Revisar relatório")
# incompativel.descrever() agora exige um argumento que antes não era necessário.Atenção
O primeiro __init__ não chama super().__init__(titulo): a validação do título não acontece e os atributos titulo e concluida não são criados. Métodos herdados podem então falhar com AttributeError.
A segunda sobrescrita exige prefixo, embora a chamada original fosse descrever(). Além disso, ela imprime em vez de retornar texto e perde o estado da tarefa. Nem o método da base nem suas garantias são executados automaticamente.
Associe cada defeito à sua consequência principal.
Toque em um item e depois no par correspondente.
Escreva uma única classe TarefaPrioritaria que corrija os dois defeitos. Ela deve chamar o inicializador da base, aceitar prioridade de 1 a 3 e sobrescrever descrever() sem exigir argumentos adicionais. Reutilize super().descrever() e retorne a descrição básica acrescida da prioridade.
Escreva pelo menos 80 caracteres (0/80).

Passo 6 de 7
Use o significado dos tipos e suas responsabilidades para decidir entre especialização por herança e colaboração por composição.
Antes de usar herança, pergunte: o novo tipo continua representando uma versão especializada do tipo existente?
TarefaPrioritaria continua sendo uma tarefa e mantém operações como concluir e descrever. A herança expressa essa especialização.Agenda reúne e utiliza tarefas, mas não representa uma tarefa. Essa relação é de composição.A decisão depende do significado e das responsabilidades dos tipos, não apenas do código que eles têm em comum.

TarefaPrioritaria amplia o conceito de Tarefa; Agenda apenas mantém e organiza objetos Tarefa.
Exemplo
TarefaPrioritaria–Tarefa: use herança porque a primeira acrescenta prioridade sem deixar de representar uma tarefa nem abandonar suas operações esperadas.
Agenda–Tarefa: use composição porque a agenda tem a responsabilidade de reunir e organizar tarefas. Ela não deve herdar de Tarefa, mesmo que queira aproveitar algum atributo ou método parecido.
Dica
Complete mentalmente: “é uma versão de” favorece herança; “tem, reúne ou usa” favorece composição. Esse teste ajuda, mas a decisão final deve considerar as responsabilidades de cada classe.
Qual decisão representa adequadamente as duas relações?
Explique por que TarefaPrioritaria pode herdar de Tarefa, enquanto Agenda deve manter tarefas por composição. Baseie sua resposta no significado dos tipos e em suas responsabilidades.
Escreva pelo menos 60 caracteres (0/60).

Passo 7 de 7
Implemente TarefaPrioritaria em um script único, execute verificações manuais e compare sua implementação com uma solução que preserva as regras da classe base.
Crie um arquivo chamado tarefas.py no seu editor. Complete apenas a classe TarefaPrioritaria: ela deve inicializar a parte comum com super().__init__, validar uma prioridade inteira de 1 a 3 e estender descrever usando o retorno de super().descrever(). Não redefina concluir, pois o comportamento herdado já atende à especialização.
Substitua o pass pela implementação de TarefaPrioritaria e execute o script.
class Tarefa:
def __init__(self, titulo):
if not isinstance(titulo, str):
raise TypeError("título deve ser uma string")
titulo = titulo.strip()
if not titulo:
raise ValueError("título não pode ser vazio")
self.titulo = titulo
self.concluida = False
def concluir(self):
self.concluida = True
def descrever(self):
marcador = "[x]" if self.concluida else "[ ]"
return f"{marcador} {self.titulo}"
class TarefaPrioritaria(Tarefa):
# Implemente os métodos __init__ e descrever.
# Requisitos:
# 1. Receber titulo e prioridade.
# 2. Reaproveitar Tarefa.__init__ com super().
# 3. Aceitar somente prioridade inteira entre 1 e 3.
# 4. Estender a descrição básica com " | prioridade: N".
pass
# Criação válida e descrição inicial
tarefa = TarefaPrioritaria("Corrigir relatório", 2)
print(tarefa.descrever())
# Uso do método concluir herdado
tarefa.concluir()
print(tarefa.descrever())
# Prioridade fora da faixa
try:
TarefaPrioritaria("Enviar relatório", 4)
except ValueError as erro:
print(f"Prioridade inválida: {erro}")
# Título inválido: a regra da classe base deve continuar valendo
try:
TarefaPrioritaria(" ", 1)
except ValueError as erro:
print(f"Título inválido: {erro}")Cole o trecho que você criou para TarefaPrioritaria. Depois, anote o resultado da descrição antes e depois de concluir() e as exceções observadas para prioridade 4 e título vazio.
Escreva pelo menos 80 caracteres (0/80).
Na inicialização, a classe base valida e cria titulo e concluida; depois, a subclasse valida e cria prioridade. Em descrever, a descrição básica é produzida sobre a mesma instância e recebe o complemento específico. Já concluir é encontrado na classe base e usado sem cópia.
O esquema separa a parte preservada da classe base da parte acrescentada pela subclasse.

A subclasse acrescenta prioridade sem duplicar a validação do título, o estado de conclusão ou a montagem da descrição básica.
Compare esta classe com a sua. Observe que self não é passado nas chamadas feitas com super().
class TarefaPrioritaria(Tarefa):
def __init__(self, titulo, prioridade):
super().__init__(titulo)
if type(prioridade) is not int:
raise TypeError("prioridade deve ser um número inteiro")
if not 1 <= prioridade <= 3:
raise ValueError("prioridade deve estar entre 1 e 3")
self.prioridade = prioridade
def descrever(self):
descricao_basica = super().descrever()
return f"{descricao_basica} | prioridade: {self.prioridade}"Exemplo
[ ] Corrigir relatório | prioridade: 2
[x] Corrigir relatório | prioridade: 2
Prioridade inválida: prioridade deve estar entre 1 e 3
Título inválido: título não pode ser vazioA mudança de [ ] para [x] confirma o uso de concluir herdado. A permanência do título e da prioridade confirma que descrever preservou a informação básica e apenas acrescentou o detalhe da subclasse.
Resumo
Use a relação entre as responsabilidades para escolher a técnica, não apenas a quantidade de código economizada.
super() quando a sobrescrita precisar preservar e estender a implementação seguinte da hierarquia.__init__, chame super().__init__ quando a parte herdada precisar ser inicializada e validada.Explique brevemente por que TarefaPrioritaria pode herdar de Tarefa, enquanto uma Agenda que reúne tarefas deve usar composição.
Escreva pelo menos 60 caracteres (0/60).
Parabéns! Você concluiu: Especializar classes com herança e super
100 XP
Milhares de cursos online em vídeo, ebooks e áudiobooks.
Para testar seus conhecimentos no decorrer dos cursos online
Gerado diretamente na galeria de fotos do seu celular e enviado ao seu e-mail
Baixe nosso aplicativo pelo QR Code ou pelos links abaixo:.
+ de 10 milhões
de alunos
Certificado grátis e
válido em todo o Brasil
60 mil exercícios
gratuitos
4,8/5 classificação
nas lojas de apps
Cursos gratuitos em
vídeo, ebooks e audiobooks