Guia de estudo

Revisão Teórica — 1ª VA (Aulas 01–12)
REVISÃO · 4h

Revisão para a 1ª VA

Aulas 01 a 12 em um único mapa

Hoje a gente fecha o ciclo: dos fundamentos de Python até tratamento de exceções. Foco no que cai na prova teórica.

Fundamentos Classes Métodos Encapsulamento Composição Herança Polimorfismo ABC Sobrecarga Exceções
Revisão Teórica — 1ª VA (Aulas 01–12)

O caminho de hoje

O que vamos revisar

Doze aulas em doze blocos. Cada bloco com o essencial: a ideia, o código mínimo e a armadilha clássica.

01

Fundamentos de Python

Variáveis, tipos, funções, condicionais. A base que sustenta tudo.

02

Classes e Objetos

Molde vs instância, __init__ e self.

03

Métodos e Dunders

Instância, classe, __str__ e __repr__.

04

Encapsulamento

_, __, @property e @setter.

05

Construtor e Composição

Defaults, validação, objetos dentro de objetos.

06

Revisão + Mini projeto

Tudo aplicado em um sistema só.

07

Herança — parte 1

É UM, super() e especialização.

08

Herança — parte 2

Sobrescrita, mixins e MRO.

09

Polimorfismo

Mesmo nome, comportamentos diferentes. Duck typing.

10

Classes Abstratas

ABC, @abstractmethod e contratos.

11

Sobrecarga

Simulação com *args/**kwargs e operadores via dunders.

12

Tratamento de Exceções

raise, try/except/finally e exceções customizadas.

Cores: azul = base · verde = estado · amarelo = relação · vermelho = abstração.
Revisão Teórica — 1ª VA (Aulas 01–12)

Bloco 01 · Fundamentos

Python em uma página

  • 🐍 Tipagem dinâmica: a variável aceita qualquer tipo, mas o tipo existe em tempo de execução.
  • 📌 Indentação é sintaxe: o bloco do if/for/def é o que estiver indentado.
  • 🔁 Tudo é objeto: até inteiros e funções têm métodos.

int / float / str / bool

Tipos básicos. type(x) revela.

list / dict / tuple / set

Coleções nativas. Diferem em mutabilidade e ordem.

def / return

Função é bloco reutilizável que recebe entrada e devolve saída.

if / elif / else

Decisão. Avalia em ordem, para no primeiro verdadeiro.

Revisão Teórica — 1ª VA (Aulas 01–12)

Bloco 01 · Fundamentos

O mínimo que cai na prova

Variável, função, condicional, laço. Se você lê isso sem travar, a base está firme.

fundamentos.py
nome = "Ana"
idade = 25
altura = 1.68
ativo = True

def classificar(idade):
    if idade < 18:
        return "menor"
    elif idade < 60:
        return "adulto"
    else:
        return "idoso"

print(classificar(idade))   # adulto

for i in range(3):
    print(f"Olá {nome}, tentativa {i + 1}")
# Olá Ana, tentativa 1
# Olá Ana, tentativa 2
# Olá Ana, tentativa 3
Revisão Teórica — 1ª VA (Aulas 01–12)

Bloco 02 · Classes e Objetos

Classe é molde. Objeto é o que sai do molde.

  • 🧱 Classe define a forma: quais atributos e quais métodos os objetos terão.
  • 🎁 Objeto (instância) é cada exemplar criado a partir da classe, com valores próprios.
  • 🪞 self é o objeto atual falando consigo mesmo dentro do método.

__init__

Construtor. Roda automaticamente ao criar o objeto.

self.atributo

Guarda o estado da instância. Cada objeto tem o seu.

Carro(...)

Chamar a classe como função cria um objeto novo.

Revisão Teórica — 1ª VA (Aulas 01–12)

Bloco 02 · Classes e Objetos

Classe mínima — Aluno

Repare: o molde é único. Os objetos são independentes — cada um carrega seu próprio estado.

aluno.py
class Aluno:
    def __init__(self, nome, matricula):
        self.nome = nome
        self.matricula = matricula
        self.notas = []

    def adicionar_nota(self, nota):
        self.notas.append(nota)

    def media(self):
        if not self.notas:
            return 0
        return sum(self.notas) / len(self.notas)

a1 = Aluno("Ana", "2026001")
a2 = Aluno("Bruno", "2026002")

a1.adicionar_nota(8)
a1.adicionar_nota(7)

print(a1.media())   # 7.5
print(a2.media())   # 0
Revisão Teórica — 1ª VA (Aulas 01–12)

Bloco 02 · Classes e Objetos

Erros clássicos do início

Esses três são os que mais caem na prova. Aprenda a reconhecer cada padrão.

Esquecer o self

  • ⚠️ Acessar atributo dentro do método sem self.
  • ⚠️ Resulta em NameError: name 'nome' is not defined.
  • ⚠️ Regra: dentro do método, todo atributo da instância usa self.

Confundir classe com instância

  • 🧩 Aluno é o molde. Aluno("Ana", "1") é o objeto.
  • 🧩 Chamar método na classe (sem instanciar) quase sempre é erro.
  • 🧩 Aluno().media() cria objeto, mas perde a referência.

Atributo mutável no __init__

  • 🧨 self.notas = [] em cada instância → cada objeto tem sua lista.
  • 🧨 Default mutável em parâmetro (def f(x=[])) compartilha entre chamadas.
  • 🧨 Para POO, sempre inicialize listas/dicts dentro do __init__.
Revisão Teórica — 1ª VA (Aulas 01–12)

Bloco 03 · Métodos e Dunders

Métodos: instância e classe

  • 🧍 Método de instância recebe self e age sobre o objeto específico.
  • 🏛️ Método de classe recebe cls e age sobre a classe inteira (factory, contadores).
  • 💬 Dunder method é método com nome em __dupla__: o Python chama em situações especiais.

self vs cls

self = a instância. cls = a classe.

@classmethod

Decorador que transforma o método em método de classe.

__str__ / __repr__

Como o objeto vira string para humano e para debug.

Revisão Teórica — 1ª VA (Aulas 01–12)

Bloco 03 · Métodos e Dunders

__str__ vs __repr__ na prática

__str__ é a versão humana (print). __repr__ é a versão técnica (debug, REPL, listas).

produto.py
class Produto:
    def __init__(self, nome, preco):
        self.nome = nome
        self.preco = preco

    def __str__(self):
        return f"{self.nome} — R$ {self.preco:.2f}"

    def __repr__(self):
        return f"Produto(nome={self.nome!r}, preco={self.preco!r})"

p = Produto("Caneta", 3.5)

print(p)          # Caneta — R$ 3.50
print(str(p))     # Caneta — R$ 3.50
print(repr(p))    # Produto(nome='Caneta', preco=3.5)
print([p, p])     # [Produto(nome='Caneta', preco=3.5), Produto(nome='Caneta', preco=3.5)]
Revisão Teórica — 1ª VA (Aulas 01–12)

Bloco 03 · Métodos e Dunders

Tipos de método — lado a lado

item detalhe
Método de instância Primeiro parâmetro é self. Acessa o estado do objeto. Uso mais comum.
Método de classe (@classmethod) Primeiro parâmetro é cls. Acessa atributos da classe. Útil para factories.
Método estático (@staticmethod) Não recebe self nem cls. Função utilitária agrupada na classe.
Dunder (__nome__) Chamado pelo Python em situações especiais (print, +, ==, len, etc.).
Revisão Teórica — 1ª VA (Aulas 01–12)

Bloco 04 · Encapsulamento

Proteger o estado do objeto

  • 🔒 Encapsular é decidir o que é interno e o que é interface pública.
  • 🤝 _ é convenção ("trate como privado"). __ é name mangling de verdade.
  • 🪟 @property e @setter expõem o atributo como propriedade, com validação no meio.

_atributo

Convenção: "é interno, não mexa." Python não impede.

__atributo

Name mangling: vira _Classe__atributo. Dificulta acesso externo.

@property

Lê como atributo, mas roda método por trás.

@x.setter

Escreve como atributo, mas roda método (com validação).

Revisão Teórica — 1ª VA (Aulas 01–12)

Bloco 04 · Encapsulamento

ContaBancaria com @property e @setter

O atributo real é _saldo. O acesso público vai por saldo, que valida.

conta.py
class ContaBancaria:
    def __init__(self, titular, saldo_inicial=0):
        self.titular = titular
        self._saldo = 0
        self.saldo = saldo_inicial   # passa pelo setter

    @property
    def saldo(self):
        return self._saldo

    @saldo.setter
    def saldo(self, valor):
        if valor < 0:
            raise ValueError("Saldo não pode ser negativo")
        self._saldo = valor

    def depositar(self, valor):
        self.saldo = self._saldo + valor   # reusa o setter

c = ContaBancaria("Ana", 100)
print(c.saldo)        # 100
c.depositar(50)
print(c.saldo)        # 150
c.saldo = -10         # ValueError: Saldo não pode ser negativo
Revisão Teórica — 1ª VA (Aulas 01–12)

Bloco 05 · Construtor e Composição

Construtor flexível e objetos dentro de objetos

  • 🎚️ Parâmetros opcionais (com default) deixam o __init__ atender vários cenários.
  • 🧰 Validar dentro do __init__ (ou via setter) garante objeto sempre consistente.
  • 🧬 Composição: um objeto guarda referência a outro. Tem-um, não é-um.

Composição (forte)

Pedido tem ItensPedido. Sem pedido, item não existe.

Agregação (fraca)

Turma tem Professor. Professor existe sem a turma.

Default = None

Use None quando o default mutável seria armadilha.

Revisão Teórica — 1ª VA (Aulas 01–12)

Bloco 05 · Construtor e Composição

Composição: Pedido tem Itens

Pedido é dono dos itens. A lista nasce no __init__ — cada pedido com a sua.

pedido.py
class Item:
    def __init__(self, nome, preco):
        self.nome = nome
        self.preco = preco

class Pedido:
    def __init__(self, cliente, itens=None):
        self.cliente = cliente
        self.itens = itens if itens is not None else []

    def adicionar(self, item):
        self.itens.append(item)

    def total(self):
        return sum(i.preco for i in self.itens)

p = Pedido("Ana")
p.adicionar(Item("Pizza", 45))
p.adicionar(Item("Refri", 8))

print(p.total())   # 53
Revisão Teórica — 1ª VA (Aulas 01–12)

Bloco 05 · Construtor e Composição

Composição vs Agregação

Mesma sintaxe em Python. A diferença é semântica: quem é dono de quem.

Composição

  • 🧱 Relação forte: parte não existe sem o todo.
  • 🧱 Itens nascem dentro do Pedido (geralmente no __init__).
  • 🧱 Casa tem Cômodos. Sem a casa, o cômodo não faz sentido.
  • 🧱 Verbo guia: "é parte de".

Agregação

  • 🔗 Relação fraca: parte existe independente do todo.
  • 🔗 Objeto chega pronto de fora, geralmente por parâmetro.
  • 🔗 Turma tem Professor. O professor vive sem a turma.
  • 🔗 Verbo guia: "está associado a".
Revisão Teórica — 1ª VA (Aulas 01–12)

Bloco 07 · Herança — parte 1

Herança: a relação É UM

  • 👨‍👩‍👧 Classe filha herda atributos e métodos da classe pai. Reuso de código com semântica clara.
  • 🎯 Use herança quando souber dizer com naturalidade: "Carro É UM Veículo".
  • 🪜 super().__init__(...) chama o construtor do pai e evita duplicação.

class Filha(Pai)

Declaração que cria o vínculo. Filha herda tudo de Pai.

super()

Acesso à versão original do pai, sem citar o nome dele.

Override

Filha redefine método do pai. Mesmo nome, comportamento próprio.

Revisão Teórica — 1ª VA (Aulas 01–12)

Bloco 07 · Herança — parte 1

Veiculo, Carro e super()

Carro é Veículo. Reaproveita marca/modelo do pai e adiciona o seu (portas).

veiculo.py
class Veiculo:
    def __init__(self, marca, modelo):
        self.marca = marca
        self.modelo = modelo

    def descrever(self):
        return f"{self.marca} {self.modelo}"

class Carro(Veiculo):
    def __init__(self, marca, modelo, portas):
        super().__init__(marca, modelo)
        self.portas = portas

    def descrever(self):
        base = super().descrever()
        return f"{base} ({self.portas} portas)"

c = Carro("Fiat", "Uno", 4)
print(c.descrever())   # Fiat Uno (4 portas)
Revisão Teórica — 1ª VA (Aulas 01–12)

Bloco 08 · Herança — parte 2

Sobrescrita, mixins e MRO

  • ✍️ Sobrescrita (override): a filha redefine o método do pai. super() permite estender em vez de substituir.
  • 🧩 Mixin: classe pequena de propósito único, combinada por herança múltipla para somar comportamento.
  • 🧭 MRO (Method Resolution Order): a ordem que o Python segue para encontrar um método. Veja com Classe.mro().

Override

Substituir totalmente. Filha define seu próprio comportamento.

Extensão via super()

Reaproveita o pai e adiciona algo a mais.

Herança múltipla

class C(A, B): junta dois pais. MRO resolve o que vier primeiro.

Revisão Teórica — 1ª VA (Aulas 01–12)

Bloco 08 · Herança — parte 2

Override + super() + MRO em ação

Gerente reaproveita o salário do Funcionário e soma uma gratificação. MRO mostra a ordem de busca.

funcionario.py
class Funcionario:
    def __init__(self, nome, salario):
        self.nome = nome
        self.salario = salario

    def calcular_bonus(self):
        return self.salario * 0.10

class Gerente(Funcionario):
    def __init__(self, nome, salario, equipe):
        super().__init__(nome, salario)
        self.equipe = equipe

    def calcular_bonus(self):
        base = super().calcular_bonus()
        return base + len(self.equipe) * 100

g = Gerente("Ana", 5000, ["Bruno", "Carla"])
print(g.calcular_bonus())     # 700.0
print(Gerente.mro())          # [Gerente, Funcionario, object]
Revisão Teórica — 1ª VA (Aulas 01–12)

Bloco 09 · Polimorfismo

Mesmo nome, comportamentos diferentes

  • 🎭 Polimorfismo: o código cliente chama obj.metodo() sem saber a classe concreta — cada objeto responde do seu jeito.
  • 🦆 Duck typing: "se quaca como pato, é pato". Python não pede família comum, pede comportamento compatível.
  • 🧹 Mata o if/elif gigante por tipo. Cada classe sabe o que faz.

Caminho 1: Herança

Subclasses sobrescrevem método da base. Contrato via hierarquia.

Caminho 2: Duck typing

Sem parentesco. Basta ter o método com o nome certo.

isinstance() com cuidado

Usar para validação, não para escolher comportamento (volta o if/elif).

Revisão Teórica — 1ª VA (Aulas 01–12)

Bloco 09 · Polimorfismo

Função poliforma sobre Animais

Repare na função fazer_falar: ela não sabe (e não precisa saber) qual classe é cada animal.

polimorfismo.py
class Animal:
    def falar(self):
        return "..."

class Cachorro(Animal):
    def falar(self):
        return "Au au!"

class Gato(Animal):
    def falar(self):
        return "Miau!"

class Pato:                  # sem herdar de Animal
    def falar(self):
        return "Quack!"

def fazer_falar(animais):
    for a in animais:
        print(a.falar())

fazer_falar([Cachorro(), Gato(), Pato()])
# Au au!
# Miau!
# Quack!
Revisão Teórica — 1ª VA (Aulas 01–12)

Bloco 09 · Polimorfismo

Herança vs Duck Typing

Os dois entregam polimorfismo. A escolha depende da garantia que você quer dar.

Polimorfismo por herança

  • 🌳 Existe uma classe base comum.
  • 🌳 O contrato fica explícito na hierarquia.
  • 🌳 Bom quando o domínio tem família clara (Animal → Cachorro/Gato).
  • 🌳 Aceita reuso de código da base.

Polimorfismo por duck typing

  • 🦆 Sem classe base. Basta o método existir com o nome certo.
  • 🦆 Mais flexível, mais frouxo. Erro só aparece em tempo de execução.
  • 🦆 Bom para juntar coisas de origens diferentes (APIs, libs, plugins).
  • 🦆 Use hasattr(obj, 'metodo') ou try/except para se proteger.
Revisão Teórica — 1ª VA (Aulas 01–12)

Bloco 10 · Classes Abstratas

Contrato que o Python cobra

  • 📜 Classe abstrata define um contrato: "toda subclasse precisa implementar esses métodos".
  • 🚫 Tentar instanciar a abstrata diretamente levanta TypeError. Erro na hora certa, não depois.
  • 🧠 Abstração é o quarto pilar da POO: foco no o que (interface) escondendo o como (implementação).

from abc import ABC

Importa o ABC, base para classes abstratas.

class X(ABC):

Marca a classe como abstrata.

@abstractmethod

Decorador que marca o método como obrigatório nas subclasses.

Revisão Teórica — 1ª VA (Aulas 01–12)

Bloco 10 · Classes Abstratas

Pagamento como contrato abstrato

A subclasse que esquecer de implementar processar() não chega nem a ser instanciada.

pagamento.py
from abc import ABC, abstractmethod

class Pagamento(ABC):
    def __init__(self, valor):
        self.valor = valor

    @abstractmethod
    def processar(self):
        ...

    def recibo(self):
        return f"Recibo de R$ {self.valor:.2f}"

class PagamentoPix(Pagamento):
    def processar(self):
        return f"Pix de R$ {self.valor:.2f} confirmado"

class PagamentoCartao(Pagamento):
    pass   # esqueceu de implementar processar()

p = PagamentoPix(50)
print(p.processar())   # Pix de R$ 50.00 confirmado
print(p.recibo())      # Recibo de R$ 50.00

c = PagamentoCartao(80)
# TypeError: PagamentoCartao é abstrata e não implementou processar()
Revisão Teórica — 1ª VA (Aulas 01–12)

Bloco 10 · Classes Abstratas

Os termos que caem na prova

item detalhe
Classe abstrata Classe que herda de ABC e existe para ser herdada — nunca instanciada.
Método abstrato Método decorado com @abstractmethod, sem implementação obrigatória na base.
Método concreto Método com corpo na classe abstrata. Pode ser herdado direto.
Subclasse concreta Herda da abstrata e implementa todos os métodos abstratos.
Contrato Conjunto de métodos abstratos que toda subclasse precisa implementar.
Revisão Teórica — 1ª VA (Aulas 01–12)

Bloco 11 · Sobrecarga

Sobrecarga em Python — duas frentes

  • 🚫 Python não tem sobrecarga de método como Java/C++: a segunda definição apaga a primeira.
  • 🎛️ A gente simula sobrecarga com defaults, *args e **kwargs — uma assinatura flexível.
  • Sobrecarga de operador é diferente: dunder methods ensinam o Python a usar +, ==, <, etc. com a sua classe.

default

def f(a, b=0): atende 1 ou 2 argumentos.

*args

Coleta posicional em tupla. Quantidade variável.

**kwargs

Coleta nomeada em dict. Argumentos por nome.

Dunders de operador

__add__, __eq__, __lt__, __str__, __len__...

Revisão Teórica — 1ª VA (Aulas 01–12)

Bloco 11 · Sobrecarga

Simulando sobrecarga com *args

Uma função, várias chamadas válidas. Sem precisar de várias versões.

calculadora.py
def somar(*numeros):
    total = 0
    for n in numeros:
        total += n
    return total

print(somar(2, 3))            # 5
print(somar(1, 2, 3, 4))      # 10
print(somar())                # 0
print(somar(*[10, 20, 30]))   # 60
Revisão Teórica — 1ª VA (Aulas 01–12)

Bloco 11 · Sobrecarga

Sobrecarga de operador — Vetor

Com __add__, __eq__ e __repr__, o Vetor passa a se comportar como um tipo nativo.

vetor.py
class Vetor:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __add__(self, outro):
        return Vetor(self.x + outro.x, self.y + outro.y)

    def __eq__(self, outro):
        return self.x == outro.x and self.y == outro.y

    def __repr__(self):
        return f"Vetor({self.x}, {self.y})"

v1 = Vetor(1, 2)
v2 = Vetor(3, 4)

print(v1 + v2)         # Vetor(4, 6)
print(v1 == Vetor(1, 2))   # True
print(v1 == v2)        # False
Revisão Teórica — 1ª VA (Aulas 01–12)

Bloco 11 · Sobrecarga

Mapa operador → dunder

item detalhe
a + b __add__(self, outro) — devolve um objeto novo, não modifica o atual.
a - b __sub__(self, outro)
a * b __mul__(self, outro)
a == b __eq__(self, outro) — se redefinir, redefina também __hash__ para usar em set/dict.
a < b __lt__(self, outro) — habilita ordenação com sorted().
str(a) / print(a) __str__(self) — representação amigável.
repr(a) __repr__(self) — representação técnica, vista em listas e debug.
len(a) __len__(self) — habilita len() na sua classe.
Revisão Teórica — 1ª VA (Aulas 01–12)

Bloco 12 · Exceções

Quando o erro precisa parar tudo

  • 🚨 Devolver None ou imprimir um aviso esconde o erro: ele estoura longe da causa, num AttributeError três telas depois.
  • 🧰 Separe quem detecta de quem trata: a função usa raise para sinalizar; quem chamou decide a reação com try/except.
  • 💡 Analogia do curso: disjuntor. O raise desarma na origem; o try/except é você no quadro de luz decidindo o que fazer.

raise

Dispara uma exceção de propósito e interrompe a função.

try

Marca o bloco arriscado que pode levantar uma exceção.

except

Captura a exceção levantada no try e executa o plano B.

Revisão Teórica — 1ª VA (Aulas 01–12)

Bloco 12 · Exceções

O quarteto try / except / else / finally

else roda só se deu certo. finally roda sempre — perfeito para limpeza.

saque.py
def sacar(saldo, valor):
    if valor > saldo:
        raise ValueError("saldo insuficiente")
    return saldo - valor

try:
    novo = sacar(100, 150)
except ValueError as erro:
    print(f"Operação negada: {erro}")    # Operação negada: saldo insuficiente
else:
    print(f"Novo saldo: {novo}")         # só roda se NÃO deu erro
finally:
    print("Encerrando operação.")         # roda SEMPRE
Revisão Teórica — 1ª VA (Aulas 01–12)

Bloco 12 · Exceções

Hierarquia + exceções customizadas

  • 🌳 Exceções são classes com herança: BaseException → Exception → ValueError / TypeError / .... Capturar a classe-mãe pega as filhas.
  • 🏷️ Exceção customizada é uma classe que herda de Exception. O nome (SaldoInsuficienteError) já documenta o erro do seu domínio.
  • 📦 Com um __init__ próprio, a exceção carrega dados do erro (saldo, valor, falta). Quem captura lê esses dados para reagir com precisão.

ValueError

Tipo certo, valor errado. Ex.: int("abc").

TypeError

Tipo errado para a operação. Ex.: "texto" + 5.

ZeroDivisionError

Divisão (ou módulo) por zero.

KeyError / IndexError

Chave ou índice que não existe.

Revisão Teórica — 1ª VA (Aulas 01–12)

Bloco 12 · Exceções

Retorno frágil × Exceção

As duas estratégias reagem ao mesmo problema. Só uma avisa de verdade.

Devolver None ou imprimir

  • Quem chama precisa lembrar de checar se veio None.
  • Erro mascarado estoura longe da causa (geralmente um AttributeError).
  • print some no meio do terminal.
  • Programa segue com dado inválido.

raise + try/except

  • A exceção para na linha exata da causa.
  • Quem chamou é obrigado a tratar (ou o programa para).
  • A mensagem diz o tipo e o motivo.
  • Dado inválido nunca segue adiante.
Revisão Teórica — 1ª VA (Aulas 01–12)

Bloco 12 · Exceções

Vocabulário de exceções

item detalhe
Exceção Objeto que representa um erro. Instância de uma classe (ValueError, TypeError, sua customizada...).
raise Levanta uma exceção de propósito. Interrompe a função e sobe o erro para quem chamou.
try / except Marca o bloco arriscado e captura um tipo específico de exceção.
else (em try) Roda apenas se o try terminou sem exceção. Mantém o try enxuto.
finally Roda sempre, com erro ou sem erro. Usado para liberar recursos (limpeza).
Hierarquia de exceções Exceções são classes com herança. Capturar a classe-mãe pega também as filhas.
Exceção customizada Classe que herda de Exception para representar um erro específico do seu domínio.
Engolir erro Anti-padrão: except: pass. O bug some da tela, mas continua vivo no programa.
EAFP Easier to Ask Forgiveness than Permission. Tente direto e trate o erro se acontecer — estilo pythônico.
Revisão Teórica — 1ª VA (Aulas 01–12)

Os 4 pilares — fechamento

POO em 4 palavras

📦

Encapsulamento

Esconder o que é interno e expor o que faz sentido. _, __, @property.

🧬

Herança

Reuso com semântica: subclasse É UM tipo da superclasse. super().

🎭

Polimorfismo

Mesma mensagem, respostas específicas. Herança ou duck typing.

🧠

Abstração

Trabalhar com o contrato (o quê), escondendo a implementação (o como).

Os quatro andam juntos. A prova pode pedir você reconhecê-los em um código pronto.
Revisão Teórica — 1ª VA (Aulas 01–12)

Armadilhas

Erros que mais caem na prova

Se você reconhece o padrão, você corrige. Treine identificar antes de ler a resposta.

1

Esquecer o self

Acessar atributo do objeto sem self dentro do método. NameError clássico.

2

Default mutável em parâmetro

def f(x=[]): a lista é compartilhada entre chamadas. Use None e inicialize dentro.

3

Confundir _ com __

_ é só convenção. __ ativa name mangling de verdade.

4

Esquecer super().__init__()

Subclasse com __init__ próprio que não chama o pai perde a inicialização da base.

5

Instanciar classe abstrata

Tentar Pagamento(50) direto levanta TypeError. Só subclasses concretas instanciam.

6

isinstance() para escolher comportamento

Volta o if/elif por tipo. Confie no polimorfismo: cada classe sabe o que faz.

7

Operador que modifica em vez de devolver

__add__ deve retornar um objeto novo, não alterar self.

Revisão Teórica — 1ª VA (Aulas 01–12)

Vocabulário

Glossário relâmpago para a prova

Saber o nome certo pesa: a prova cobra termo técnico, não só código.

Classe

Molde que define atributos e comportamento de objetos.

Objeto / Instância

Cada exemplar criado a partir da classe, com estado próprio.

Atributo

Dado guardado dentro do objeto (ou da classe).

Método

Função definida dentro da classe, agindo sobre o objeto.

self

Referência ao próprio objeto, primeiro parâmetro do método de instância.

__init__

Construtor: roda ao criar o objeto, define o estado inicial.

@property

Decorador que faz um método ser acessado como atributo.

Herança

Relação É UM. Subclasse herda atributos e métodos da superclasse.

super()

Acessa o comportamento da superclasse sem nomeá-la.

Override

Sobrescrita: subclasse redefine método herdado.

Polimorfismo

Mesmo nome de método, comportamentos diferentes por tipo.

Duck typing

Compatibilidade por comportamento, não por hierarquia.

Classe abstrata

Herda de ABC, define contrato via @abstractmethod.

Dunder method

Método com nome em __dupla__: o Python chama em situações especiais.

MRO

Ordem de resolução de métodos em herança múltipla.

Exceção

Objeto que representa um erro. Levantado com raise, capturado com try/except.

raise

Dispara uma exceção de propósito e interrompe a função.

Exceção customizada

Classe que herda de Exception e representa erro do seu domínio.

Revisão Teórica — 1ª VA (Aulas 01–12)

Como ler código em prova

Roteiro de 5 passos para ler qualquer código POO

Treine este roteiro nas questões de "o que esse código imprime?"

1

Mapeie as classes

Quais classes existem? Quem herda de quem? Anote a hierarquia na margem.

2

Leia o __init__ de cada uma

Que atributos cada objeto guarda? Anote os campos.

3

Liste os métodos sobrescritos

Mesmo nome aparecendo em pai e filha? Veja qual versão será chamada.

4

Simule a execução linha a linha

Crie os objetos no papel. Anote o estado depois de cada chamada.

5

Confirme a saída

Para cada print, anote o que sai. Para cada erro, anote o tipo (TypeError, ValueError, AttributeError).

Revisão Teórica — 1ª VA (Aulas 01–12)

Autoavaliação

Você está pronto se consegue...

  • Explicar a diferença entre classe e objeto sem olhar.
  • Escrever uma classe com __init__, atributos e dois métodos.
  • Apontar quando usar _ (convenção) e quando usar __ (mangling).
  • Mostrar @property e @setter em uma classe com validação.
  • Diferenciar composição de agregação com um exemplo real.
  • Implementar herança com super() chamando o construtor do pai.
  • Reconhecer override, mostrar com e sem super().
  • Explicar polimorfismo com herança E com duck typing.
  • Criar uma classe abstrata com @abstractmethod e uma subclasse concreta.
  • Sobrecarregar __add__, __eq__ e __repr__ em uma classe sua.
  • Diferenciar return None (frágil) de raise (sinaliza o erro na origem).
  • Mostrar try / except / else / finally e dizer quando cada um roda.
  • Criar uma exceção customizada que herda de Exception e carrega dados do erro.
  • Listar os 4 pilares da POO e dar um exemplo de cada.
Revisão Teórica — 1ª VA (Aulas 01–12)

Dicas finais

Estratégia para a 1ª VA

  • 🧭 Leia toda a prova antes de começar. Identifique o que é teoria pura e o que é leitura de código.
  • ✏️ Em questões de código, escreva o estado das variáveis na margem. Não confie só na cabeça.
  • 🧪 Se travar, vá para a próxima. Volta depois com a cabeça mais leve.
  • 🪤 Cuidado com pegadinhas de nome: __ (mangling), atributos de classe vs instância, default mutável.
  • 📚 Releia o slide 37 (glossário), o 36 (armadilhas) e o 34 (vocabulário de exceções) na noite anterior.
Revisão Teórica — 1ª VA (Aulas 01–12)

Resumo em uma linha cada

O essencial das 12 aulas

  • Classe é molde, objeto é instância — cada objeto carrega seu próprio estado.
  • self é o objeto atual; __init__ roda no momento da criação.
  • Métodos de instância usam self, métodos de classe usam cls.
  • __str__ é para humano, __repr__ é para debug — defina os dois quando puder.
  • Encapsulamento: _ (convenção), __ (mangling), @property + @setter para controle real.
  • Composição é "tem-um forte"; agregação é "tem-um fraco".
  • Herança é "é-um"; use super() para reaproveitar e estender o pai.
  • Sobrescrita: filha redefine o método; com super() ela estende em vez de substituir.
  • Polimorfismo: mesmo nome, comportamentos próprios — via herança ou duck typing.
  • Classe abstrata (ABC + @abstractmethod) garante contrato em tempo de criação do objeto.
  • Sobrecarga em Python: defaults, *args e **kwargs simulam; dunders ensinam operadores.
  • Exceções: raise quem detecta, try/except quem trata; exceções customizadas falam a língua do domínio.