Herança é o pilar da POO que permite que uma classe (filha) adquira os atributos e métodos de outra classe (pai). O objetivo principal é o reuso de código e a especialização.
Só use herança se você puder dizer que a classe B 'é um' tipo de A:
__str__).Basta colocar o nome da classe base entre parênteses ao definir a subclasse.
class Pai:
def falar_sobrenome(self):
print('Silva')
class Filho(Pai): # Herança aqui
pass
# Exemplo de uso:
obj = Filho()
obj.falar_sobrenome() # Saída: Silva (Herdado!) Se a filha define um __init__, ela 'esconde' o do pai. O super().__init__() permite que o pai inicialize seus atributos antes da filha adicionar os novos.
| Sem super() | Com super() |
|---|---|
| Atributos do pai não são criados ou dão erro | Atributos do pai são inicializados corretamente |
| Código duplicado e frágil | Código modular e limpo (reuso) |
Sempre chame super().__init__ na primeira linha do construtor da filha para garantir a integridade dos dados.
Programação Orientada a Objetos com Python
Tecnologia em Análise e Desenvolvimento de Sistemas
agenda de hoje
Entender por que herança é sobre especialização e não apenas copiar código.
Como declarar o parentesco e delegar tarefas para o pai via super().
Construção passo a passo da hierarquia de Veículos e o desafio de RH.
motivação
Defina o comportamento comum uma única vez no pai. As filhas herdam tudo e focam apenas no que as torna únicas.
fundamento
Tem motor e rodas, mas adiciona portas e porta-malas.
Recebe salário, mas adiciona bônus e equipe.
Respira e come, mas adiciona latido e raça.
sintaxe básica
Em Python, a herança é declarada passando o pai entre parênteses. A filha nasce com 100% do DNA do pai.
class Veiculo:
def __init__(self, marca):
self.marca = marca
def buzinar(self):
print("Beep beep!")
class Carro(Veiculo): # Carro herda de Veiculo
pass
meu_carro = Carro("Toyota")
meu_carro.buzinar() # Herdado! Beep beep! o poder do super()
O super() evita que você repita código. O pai cuida do que é dele.
class Veiculo:
def __init__(self, marca, modelo):
self.marca = marca
self.modelo = modelo
class Carro(Veiculo):
def __init__(self, marca, modelo, portas):
# Chama o construtor do pai primeiro!
super().__init__(marca, modelo)
self.portas = portas # Atributo exclusivo da filha super().__init__ sempre na primeira linha do construtor da filha.prática guiada · parte 1
Vamos criar o pai de todos, com as regras de negócio comuns.
class Veiculo:
_total = 0
def __init__(self, marca, modelo, ano):
self.marca = marca
self.modelo = modelo
self.ano = ano
self.ligado = False
Veiculo._total += 1
def ligar(self):
self.ligado = True
print(f"{self.modelo} ligado.")
def __str__(self):
status = "ON" if self.ligado else "OFF"
return f"{self.marca} {self.modelo} ({self.ano}) - {status}" prática guiada · parte 2
O Carro herda de Veiculo e adiciona o controle de portas.
class Carro(Veiculo):
def __init__(self, marca, modelo, ano, portas=4):
super().__init__(marca, modelo, ano)
self.portas = portas
def abrir_porta(self):
print(f"Abrindo {self.portas} portas do {self.modelo}.")
def __str__(self):
base = super().__str__()
return f"{base} | {self.portas} portas" prática guiada · parte 3
A Moto herda do mesmo pai, mas tem comportamentos diferentes.
class Moto(Veiculo):
def __init__(self, marca, modelo, ano, cilindradas):
super().__init__(marca, modelo, ano)
self.cilindradas = cilindradas
def empinar(self):
if self.ligado:
print(f"RANDANDAN! {self.modelo} no grau!")
else:
print("Ligue a moto primeiro!")
def __str__(self):
base = super().__str__()
return f"{base} | {self.cilindradas}cc" prática guiada · parte 4
O Caminhão herda de Veiculo e adiciona controle de carga máxima.
class Caminhao(Veiculo):
def __init__(self, marca, modelo, ano, carga_maxima):
super().__init__(marca, modelo, ano)
self.carga_maxima = carga_maxima # em toneladas
def carregar(self, peso):
if peso > self.carga_maxima:
print(f"⚠️ Excesso de peso! Limite: {self.carga_maxima}t")
else:
print(f"📦 Carregando {peso}t no {self.modelo}.")
def __str__(self):
base = super().__str__()
return f"{base} | Carga Max: {self.carga_maxima}t" visão geral
Veja como o código fica limpo quando o pai absorve o trabalho pesado.
exercício em aula
exibir(). calcular_bonus(). O Gerente deve ganhar o salário base + bônus de 15% no seu método específico.
desafio RH · passo 1
Começamos pelo 'pai'. Ele define o que é comum a qualquer trabalhador da empresa.
class Funcionario:
def __init__(self, nome, salario_base):
self.nome = nome
self.salario_base = salario_base
def exibir_dados(self):
return f"Func: {self.nome} | Salário: R$ {self.salario_base:.2f}" desafio RH · passo 2
O Gerente 'É UM' funcionário, mas tem um departamento e um bônus.
class Gerente(Funcionario):
def __init__(self, nome, salario_base, departamento):
# Delegamos nome e salário para o pai!
super().__init__(nome, salario_base)
self.departamento = departamento
def calcular_bonus(self):
# Regra: 15% do salário base
return self.salario_base * 0.15 desafio RH · passo 3
Vamos usar o super() para construir um relatório que soma os dados do pai com os do filho.
def exibir_dados(self):
# 1. Pegamos a string base do pai
base = super().exibir_dados()
# 2. Calculamos o valor final
total = self.salario_base + self.calcular_bonus()
# 3. Retornamos tudo combinado
return f"{base} | Depto: {self.departamento} | Total: R$ {total:.2f}" desafio RH · passo 4
Comparando o comportamento de um funcionário comum vs. um gerente.
f1 = Funcionario("Carlos", 2500)
g1 = Gerente("Marta", 6000, "Vendas")
print(f1.exibir_dados())
# Saída: Func: Carlos | Salário: R$ 2500.00
print(g1.exibir_dados())
# Saída: Func: Marta | Salário: R$ 6000.00 | Depto: Vendas | Total: R$ 6900.00 atenção
Se a filha tem __init__, ela apaga o do pai. Sem super, os atributos do pai não existirão.
O super().__init__(...) precisa receber exatamente o que o pai pede.
Usar herança só pra ganhar métodos, mesmo que a relação não seja 'É UM'.
fechamento
para casa
Hora de fixar o conceito de hierarquia.
Exercícios: 1 ao 4
Exercícios: 5 ao 9
Exercícios: 10 ao 13
Exercícios: 14 e 15
exercícios para casa · nível fácil
Demonstre a herança básica: Crie uma classe Pai com um método mensagem() que imprime uma saudação. Crie a classe Filho que herda de Pai e use pass para provar que o filho já nasce sabendo saudar.
Crie uma classe base Animal com o atributo nome e o método emitir_som(). Em seguida, crie a classe Cachorro herdando dela. O objetivo é garantir que o cachorro acesse o nome definido no pai.
Modele um sistema de hardware: Crie Equipamento com os atributos tensao e ligado. Crie Computador herdando dele e adicionando memoria_ram. Verifique se o computador possui os 3 atributos.
Geometria básica: Crie a classe Forma que define apenas a cor. Crie a classe Circulo que herda essa cor e especializa o objeto adicionando o atributo raio.
exercícios para casa · nível médio
Crie Funcionario (nome, salario). Crie Desenvolvedor que herda dele e adiciona o atributo linguagem_principal. Use obrigatoriamente o super().__init__ para inicializar os dados comuns no pai.
Teste a herança multinível: Crie Veiculo (marca). Crie Terrestre (herda de Veiculo e adiciona rodas). Crie Carro (herda de Terrestre e adiciona portas). Verifique se o carro possui marca, rodas e portas.
Sistemas financeiros: Crie Conta (titular, saldo). Crie ContaPoupanca que adiciona taxa_juros e um método aplicar_juros() que aumenta o saldo atual com base na taxa definida.
Gestão de estoque: Crie Produto (nome, preco). Crie Livro que adiciona o atributo autor. Implemente um método __str__ no Livro que exiba o nome, o autor e o preço formatado.
Controle de acesso: Crie Usuario (username, senha). Crie Admin que herda dele e adiciona nivel_acesso (inteiro). Adicione um método eh_super_admin() que retorna True se o nível for maior que 5.
exercícios para casa · nível difícil
Segurança de dados: No exercício 07 (Conta), torne o saldo privado (_saldo). Certifique-se de que a ContaPoupanca consiga interagir com o saldo apenas através de métodos ou propriedades protegidas.
Composição e Herança: Crie Prato (nome, preco). Crie Pizza que adiciona uma lista de ingredientes (relação de composição). O método __str__ da pizza deve listar o nome e todos os ingredientes.
Agregação e Herança: Crie Pessoa como base. Aluno e Professor herdam dela. O Professor deve possuir uma lista de Alunos (agregação). Crie um método no professor para listar seus alunos.
Garantia de integridade: Crie Caminhao herdando de Veiculo. No __init__ do caminhão, valide se a carga_maxima não é negativa antes de chamar o construtor do pai via super.
exercícios para casa · nível avançado
Polimorfismo inicial: Crie Produto base. Crie Smartphone e Notebook com especificações únicas. Crie uma classe Carrinho que aceita qualquer um deles e calcula o valor total da compra.
Sistemas de jogos: Crie Entidade base (nome, vida). Crie Heroi (adiciona mana) e Inimigo (adiciona drop_xp). Implemente uma lógica de batalha simples onde ambos manipulam os atributos herdados.
Vamos aprender Override avançado, MRO e Herança Múltipla.