Programação Orientada a Objetos com Python
Tecnologia em
Análise e Desenvolvimento de Sistemas
🎁
Isso é um objeto
Características → atributos
cor = "preto"
marca = "Samsung"
bateria = 80
Ações → métodos
ligar()
tirar_foto()
carregar()
Atributos:
marca, modelo, bateria, cor
Métodos:
ligar(), tirar_foto(), carregar()
Atributos:
titular, saldo, agência
Métodos:
depositar(), sacar(), extrato()
Atributos:
nome, matrícula, notas
Métodos:
adicionar_nota(), media(), situacao()
Uma classe não é o objeto — é a descrição de como o objeto vai ser.
# Classe = molde
class Cachorro:
pass # ainda vazio, mas já é uma classe!
# Objetos = instâncias do molde
rex = Cachorro()
bolt = Cachorro()
rex e bolt são dois objetos diferentes
criados a partir do mesmo molde.
__init__
__init__ é chamado automaticamente quando você cria um
objeto. É onde você define os atributos iniciais.
class Cachorro:
def __init__(self, nome, raca, idade):
self.nome = nome # atributo de instância
self.raca = raca
self.idade = idade
rex = Cachorro("Rex", "Labrador", 3)
bolt = Cachorro("Bolt", "Husky", 1)
print(rex.nome) # Rex
print(bolt.raca) # Husky
self é a forma de Python dizer "este objeto
específico". Sem self, os atributos não pertencem ao
objeto.
self?
self é a referência ao próprio objeto. Python passa o
objeto automaticamente como primeiro argumento em todo método.
class Cachorro:
def latir(): # falta self
print("Au!")
rex = Cachorro()
rex.latir() # ERRO!
class Cachorro:
def latir(self): # correto
print("Au!")
rex = Cachorro()
rex.latir() # Au!
rex.latir() em
Cachorro.latir(rex) nos bastidores. O
self é o rex.
Métodos são funções que vivem dentro da classe e operam sobre os dados do objeto.
class Cachorro:
def __init__(self, nome, idade):
self.nome = nome
self.idade = idade
def latir(self):
print(f"{self.nome} diz: Au!")
def apresentar(self):
print(f"Meu nome é {self.nome} e tenho {self.idade} anos.")
rex = Cachorro("Rex", 3)
rex.latir() # Rex diz: Au!
rex.apresentar() # Meu nome é Rex e tenho 3 anos.
Alterar um objeto não afeta os outros.
class Pessoa:
def __init__(self, nome, idade):
self.nome = nome
self.idade = idade
def aniversario(self):
self.idade += 1
print(f"Feliz aniversário, {self.nome}! Agora tem {self.idade} anos.")
ana = Pessoa("Ana", 22)
pedro = Pessoa("Pedro", 30)
ana.aniversario() # Feliz aniversário, Ana! Agora tem 23 anos.
print(pedro.idade) # 30 — Pedro não mudou
A calculadora que você fez na semana passada, agora com memória.
class Calculadora:
def __init__(self):
self.historico = [] # atributo: guarda operações
def somar(self, a, b):
resultado = a + b
self.historico.append(f"{a} + {b} = {resultado}")
return resultado
def ver_historico(self):
for item in self.historico:
print(item)
calc = Calculadora()
print(calc.somar(10, 5)) # 15
print(calc.somar(3, 7)) # 10
calc.ver_historico()
historico. Isso é impossível com funções avulsas.
__str__
Define o que aparece quando você faz print(objeto).
class Produto:
def __init__(self, nome, preco):
self.nome = nome
self.preco = preco
def __str__(self):
return f"Produto: {self.nome} — R$ {self.preco:.2f}"
camiseta = Produto("Camiseta", 49.90)
print(camiseta) # Produto: Camiseta — R$ 49.90
__str__, o print mostraria algo como
<__main__.Produto object at 0x...>. Com ele, você
controla a saída.
Nem todo atributo precisa ser passado no __init__.
class ContaBancaria:
banco = "Banco Python" # atributo de CLASSE — igual para todos
def __init__(self, titular, saldo):
self.titular = titular # atributo de INSTÂNCIA — único
self.saldo = saldo
c1 = ContaBancaria("Ana", 1000)
c2 = ContaBancaria("Pedro", 500)
print(c1.banco) # Banco Python
print(c2.banco) # Banco Python
print(c1.titular) # Ana
print(c2.titular) # Pedro
self no método — todo
método de instância precisa de self como primeiro
parâmetro, sem exceção
self. para acessar atributos
— dentro da classe, sempre self.nome, nunca só
nome
__init__ com self.lista = [], não
no corpo da classe
obj.metodo() é correto, obj.metodo sem
parênteses não executa o método
Cachorro é a classe (molde),
rex = Cachorro() é o objeto (instância)
Quando algo não funciona, essas ferramentas ajudam a entender o que está acontecendo.
class Pessoa:
def __init__(self, nome, idade):
self.nome = nome
self.idade = idade
p = Pessoa("Ana", 22)
# Ver todos os atributos do objeto
print(vars(p))
# {'nome': 'Ana', 'idade': 22}
# Confirmar o tipo do objeto
print(type(p))
# <class '__main__.Pessoa'>
# Ver se é instância de uma classe
print(isinstance(p, Pessoa))
# True
Guarde esse template — é o ponto de partida para qualquer classe que você criar.
class MinhaClasse:
atributo_de_classe = "valor" # compartilhado
def __init__(self, param1, param2):
self.param1 = param1 # atributo de instância
self.param2 = param2
def meu_metodo(self):
return f"valor: {self.param1}"
def __str__(self):
return f"MinhaClasse({self.param1})"
# uso
obj = MinhaClasse("a", "b")
print(obj)
obj.meu_metodo()
Vamos criar uma classe Aluno do zero, juntos.
Criar classe Aluno com nome,
matricula e notas (lista vazia).
Método __str__ que exibe o aluno.
Adicionar adicionar_nota(nota) e
calcular_media() que retorna a média das notas.
Método situacao(): Aprovado (≥7), Recuperação
(5–6.9) ou Reprovado (<5).
class Aluno:
def __init__(self, nome, matricula):
self.nome = nome
self.matricula = matricula
self.notas = [] # lista vazia
def __str__(self):
return f"Aluno: {self.nome} | Matrícula: {self.matricula}"
# Teste
a1 = Aluno("Ana Silva", "2026001")
print(a1)
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 calcular_media(self):
if len(self.notas) == 0:
return 0
return sum(self.notas) / len(self.notas)
def situacao(self):
media = self.calcular_media()
if media >= 7:
return "Aprovado"
elif media >= 5:
return "Recuperação"
else:
return "Reprovado"
def __str__(self):
return (f"Aluno: {self.nome} | "
f"Média: {self.calcular_media():.1f} | "
f"{self.situacao()}")
a1 = Aluno("Ana Silva", "2026001")
a1.adicionar_nota(8.0)
a1.adicionar_nota(7.5)
a1.adicionar_nota(9.0)
print(a1)
self aparece na definição mas não na
chamada?rex.latir() vira
Cachorro.latir(rex) nos bastidores.
Cachorro e
Cachorro()?Cachorro é a classe em si.
Cachorro() chama o construtor e cria um
objeto.
__init__?__init__ vazio padrão. Mas na
prática, quase toda classe precisa de um.
class NomeDaClasse: — como declarar uma
classe
__init__(self, ...) — construtor, onde nascem os
atributos
self — a referência ao próprio objeto
self
__str__ — como o objeto se apresenta no
print
Faça o máximo que conseguir e anote suas dúvidas para a próxima aula.
Crie funções somar(a,b),
subtrair(a,b), multiplicar(a,b) e
dividir(a,b). Divisão retorna mensagem se b for
zero. Teste todas. (Revisão da aula 01)
Crie calcular_imc(peso, altura) e
classificar_imc(imc). Peça os dados ao usuário e
exiba o resultado. (Revisão da aula 01)
Crie uma classe Carro com atributos
marca, modelo e ano.
Adicione __str__ que exiba as informações. Crie
dois objetos diferentes e imprima ambos.
Crie uma classe Pessoa com nome e
idade. Adicione um método
apresentar(self) que imprime uma saudação. Crie
três instâncias com dados diferentes.
Crie uma classe Retangulo com
largura e altura. Adicione os métodos
area(self) e perimetro(self) que
retornam os respectivos valores.
Crie ContaBancaria com titular e
saldo. Métodos depositar(valor) e
sacar(valor) — saque só funciona com saldo
suficiente. Adicione __str__.
Crie Produto com nome,
preco e estoque. Métodos
vender(qtd) — sem deixar negativo — e
repor(qtd).
Sem olhar os slides — implemente do zero a classe
Aluno com nome,
matricula, lista de notas,
adicionar_nota, calcular_media e
situacao.
Crie Cronometro com segundos = 0.
Método avancar(s) soma segundos e
em_minutos(self) retorna string como
"2 minutos e 35 segundos".
Crie Temperatura com atributo celsius.
Métodos para_fahrenheit() e
para_kelvin(). __str__ exibe as três
escalas.
Implemente a Calculadora do slide 8. Adicione
limpar_historico() e
ultimo_resultado() que retorna o último item ou
mensagem se vazio.
Crie Pilha com lista vazia. Métodos
empilhar(item), desempilhar() —
retorna None se vazia —, topo() e
esta_vazia(). Teste com 5 operações.
Crie Turma com lista de alunos. Métodos
matricular(aluno), listar(),
media_turma() e melhores_alunos() —
retorna quem tem média acima de 7. Use a classe
Aluno do exercício 8.
Crie Agenda com dicionário de contatos. Métodos
adicionar(nome, telefone),
buscar(nome), remover(nome) e
listar() em ordem alfabética.
Expanda o exercício 6 adicionando extrato (lista),
ver_extrato() com tipo e valor de cada operação e
transferir(outra_conta, valor).
Crie Livro com titulo,
autor e disponivel=True. Crie
Biblioteca com métodos
adicionar_livro, emprestar,
devolver e listar_disponiveis.
Crie Vetor2D com x e y.
Implemente __str__, __add__ (soma de
vetores), __eq__ e magnitude() — use
import math.
Crie JogoAdivinhacao com número sorteado entre 1 e
100, contador de tentativas e máximo de 10. Métodos
adivinhar(n) e reiniciar(). Use
import random.
Crie Matriz com linhas e
colunas (grade de zeros). Métodos
definir(l,c,v), obter(l,c),
__str__ formatado e somar(outra) com
verificação de dimensões.
Crie Personagem com vida=100,
ataque e defesa. Método
atacar(outro) — dano = max(0, ataque - defesa do
outro) — e esta_vivo(). Simule um combate em loop
até um morrer.
Vamos aprofundar o uso de métodos, entender o self em
detalhes e aprender sobre __str__,
__repr__ e outras formas de representar um objeto.