Mentalidade de objetos: como “enxergar” o problema
Em Programação Orientada a Objetos (POO), você organiza o código em torno de objetos que representam coisas (reais ou abstratas) do seu domínio: um usuário, um produto, uma conta bancária, um pedido. Cada objeto combina dados (estado) e comportamentos (ações) relacionados.
Uma forma prática de pensar é: substantivos viram candidatos a objetos (Conta, Produto, Usuário) e verbos viram candidatos a métodos (depositar, aplicar_desconto, alterar_email). O objetivo é reduzir “variáveis soltas” e “funções genéricas” e aproximar o código do modelo mental do problema.
Três perguntas para modelar
- O que é a entidade? (ex.: ContaBancaria)
- Quais dados ela precisa guardar? (ex.: titular, saldo)
- Quais ações fazem sentido para ela? (ex.: depositar, sacar)
Classe vs. objeto (instância): definição clara
Classe é um “molde” que descreve como os objetos daquele tipo devem ser: quais atributos terão e quais métodos podem executar.
Objeto (ou instância) é um “exemplar” criado a partir da classe. Cada instância tem seu próprio estado.
| Conceito | Analogia | Em Python |
|---|---|---|
| Classe | Planta de uma casa | class Casa: ... |
| Instância | Uma casa construída | casa1 = Casa() |
| Atributo | Características | casa1.cor |
| Método | Ações | casa1.pintar() |
Notação de ponto: acessando membros
Em objetos, você usa a notação de ponto para acessar atributos e métodos:
- Ouça o áudio com a tela desligada
- Ganhe Certificado após a conclusão
- + de 5000 cursos para você explorar!
Baixar o aplicativo
objeto.atributopara ler/alterar dadosobjeto.metodo()para executar um comportamento
Exemplo rápido (sem ainda se preocupar com validações):
class Produto: pass produto = Produto() produto.nome = "Camiseta" produto.preco = 59.90 print(produto.nome) print(produto.preco)Esse estilo funciona, mas em geral você vai preferir inicializar atributos no momento da criação do objeto, para evitar instâncias “pela metade”.
Passo a passo: criando uma classe e instanciando
1) Comece com uma classe mínima
Uma classe pode começar vazia (com pass) para você testar a ideia:
class Usuario: pass2) Crie instâncias (objetos)
u1 = Usuario() u2 = Usuario() print(u1) print(u2)u1 e u2 são instâncias diferentes: cada uma pode ter seus próprios dados.
3) Adicione atributos via notação de ponto (primeiro contato)
u1.nome = "Ana" u2.nome = "Bruno" print(u1.nome) print(u2.nome)Isso demonstra o conceito de instância, mas ainda não garante que todo Usuario terá nome. Para tornar o objeto consistente, use um método de inicialização.
Exemplo incremental 1: Produto (estado + comportamento simples)
Objetivo do modelo
- Entidade: Produto
- Estado: nome, preco
- Comportamento: aplicar desconto
Passo a passo
Passo 1 — Defina a classe com um inicializador
class Produto: def __init__(self, nome, preco): self.nome = nome self.preco = precoPasso 2 — Crie instâncias
p1 = Produto("Camiseta", 59.90) p2 = Produto("Tênis", 199.90)Passo 3 — Acesse atributos com ponto
print(p1.nome) print(p1.preco)Passo 4 — Adicione um método (comportamento)
class Produto: def __init__(self, nome, preco): self.nome = nome self.preco = preco def aplicar_desconto(self, percentual): self.preco = self.preco * (1 - percentual)Passo 5 — Use o método
p1 = Produto("Camiseta", 59.90) p1.aplicar_desconto(0.10) print(p1.preco) # 53.91Note como o método altera o estado do próprio objeto (o preço daquele produto específico).
Exemplo incremental 2: ContaBancaria (responsabilidades e limites)
Objetivo do modelo
- Entidade: ContaBancaria
- Estado: titular, saldo
- Comportamento: depositar, sacar
- Limite: não permitir saque maior que o saldo
Implementação passo a passo
Passo 1 — Estruture a classe e inicialize o estado
class ContaBancaria: def __init__(self, titular, saldo_inicial=0.0): self.titular = titular self.saldo = float(saldo_inicial)Passo 2 — Depósito
class ContaBancaria: def __init__(self, titular, saldo_inicial=0.0): self.titular = titular self.saldo = float(saldo_inicial) def depositar(self, valor): self.saldo += float(valor)Passo 3 — Saque com regra de negócio
class ContaBancaria: def __init__(self, titular, saldo_inicial=0.0): self.titular = titular self.saldo = float(saldo_inicial) def depositar(self, valor): self.saldo += float(valor) def sacar(self, valor): valor = float(valor) if valor > self.saldo: return False self.saldo -= valor return TruePasso 4 — Use a classe e observe a notação de ponto
conta = ContaBancaria("Ana", 100) conta.depositar(50) print(conta.saldo) # 150.0 ok = conta.sacar(200) print(ok) # False print(conta.saldo) # 150.0 ok = conta.sacar(30) print(ok) # True print(conta.saldo) # 120.0Perceba a divisão de responsabilidades: quem “sabe” como sacar e validar saldo é a própria conta. Quem usa a conta apenas chama conta.sacar(...).
Exemplo incremental 3: Usuario (modelando dados e ações do domínio)
Objetivo do modelo
- Entidade: Usuario
- Estado: nome, email, ativo
- Comportamento: desativar, alterar email
Implementação
class Usuario: def __init__(self, nome, email): self.nome = nome self.email = email self.ativo = True def desativar(self): self.ativo = False def alterar_email(self, novo_email): self.email = novo_emailUso:
u = Usuario("Bruno", "bruno@exemplo.com") print(u.ativo) u.desativar() print(u.ativo) u.alterar_email("bruno.novo@exemplo.com") print(u.email)Como identificar entidades, responsabilidades e limites do objeto
Entidade
Uma entidade costuma ter identidade no domínio (mesmo que seus dados mudem): um usuário continua sendo o mesmo usuário; uma conta continua sendo a mesma conta.
Responsabilidade
Responsabilidade é o que o objeto deve “cuidar” para manter seu estado coerente. Exemplo: ContaBancaria deve impedir saque acima do saldo; Produto deve saber recalcular seu preço ao aplicar desconto.
Limites
Limites são o que não pertence ao objeto. Exemplo: ContaBancaria não precisa “saber” como desenhar uma tela; ela deve focar em regras de saldo, depósito e saque. Separar limites evita classes “faz-tudo”.
Exercícios (modelagem e leitura de código)
1) Identificação de entidades (substantivos)
Leia o cenário: “Um sistema de loja precisa cadastrar produtos, clientes e pedidos. Um pedido tem itens (produto + quantidade) e um status (aberto, pago, enviado).”
- Liste pelo menos 4 entidades candidatas a classes.
- Para cada entidade, escreva 2 atributos prováveis.
- Para cada entidade, escreva 2 métodos prováveis.
2) Responsabilidade e limite
Considere a classe ContaBancaria.
- Quais regras devem ficar dentro de
ContaBancariae por quê? (ex.: validar saldo, impedir valores negativos) - Cite 2 responsabilidades que não deveriam ficar em
ContaBancaria(ex.: salvar em arquivo, enviar e-mail).
3) Complete a classe Produto
Implemente um método aumentar_preco(percentual) que aumente o preço do produto. Depois, crie dois produtos e aplique aumento em apenas um deles para verificar que cada instância mantém seu próprio estado.
class Produto: def __init__(self, nome, preco): self.nome = nome self.preco = preco def aumentar_preco(self, percentual): # implemente aqui pass4) Leitura de instâncias e notação de ponto
Sem executar, responda:
class Usuario: def __init__(self, nome, email): self.nome = nome self.email = email self.ativo = True def desativar(self): self.ativo = False u1 = Usuario("Ana", "ana@exemplo.com") u2 = Usuario("Bruno", "bruno@exemplo.com") u1.desativar() print(u1.ativo, u2.ativo)- O que será impresso?
- Explique por que desativar
u1não alterau2.
5) Modelagem guiada (entidade do mundo real)
Escolha uma destas opções e modele uma classe com 3 atributos e 3 métodos: Livro, ReservaDeHotel ou CarrinhoDeCompras.
- Escreva o nome da classe e seus atributos.
- Descreva as responsabilidades principais (o que ela deve garantir).
- Escreva um pequeno trecho criando 2 instâncias e chamando 2 métodos em cada uma.