Módulo 10 - Orientação a objetos: classes
Prática: a classe ContaBancaria
11 min de leitura · por Cesar Gargiulo, revisado pela equipe ValorFinal e GuardiaSec · Atualizado em 01/07/2026
O que você vai aprender
- Montar a classe ContaBancaria com __init__, métodos e __str__.
- Aplicar regras nos métodos depositar e sacar, validando os valores.
- Criar objetos e operar neles, acompanhando o saldo mudar.
- Enxergar os conceitos do módulo trabalhando juntos em um exemplo real.
Ouvir o resumo desta aula
Um recap de cerca de 2 minutos na voz do Valim, para ouvir no trânsito ou na academia.
Ler a transcrição do resumo
Resumo da aula: Prática: a classe ContaBancaria.
Os objetivos desta aula. Montar a classe ContaBancaria com __init__, métodos e __str__. Aplicar regras nos métodos depositar e sacar, validando os valores. Criar objetos e operar neles, acompanhando o saldo mudar. Enxergar os conceitos do módulo trabalhando juntos em um exemplo real.
Veja o essencial, parte por parte.
Montando a classe completa. A ContaBancaria junta o __init__ (titular e saldo), métodos e __str__.
Criando contas e operando. Adicione um método transferir(self, destino, valor) que saca de um e deposita no outro.
O que você construiu. Olhe para trás.
Esse foi o resumo do essencial. Para se aprofundar, leia a aula completa e responda os exercícios.
Montando a classe completa
Esta prática reúne tudo do módulo em uma classe só. A ContaBancaria guarda o titular e o saldo como atributos de instância, sabe depositar e sacar com regras claras, e se descreve com um __str__. Vamos montá-la por partes e, ao final, operar nela. Digite cada trecho no Playground e rode, acompanhando o saldo mudar. Ver os conceitos funcionando juntos fixa muito mais que ler sobre eles separados.
class ContaBancaria:
banco = "ValorBank" # atributo de classe: igual para todas
def __init__(self, titular, saldo=0):
self.titular = titular
self.saldo = saldo
def depositar(self, valor):
if valor <= 0:
print("Valor de deposito deve ser positivo.")
return False
self.saldo += valor
return True
def sacar(self, valor):
if valor <= 0:
print("Valor de saque deve ser positivo.")
return False
if valor > self.saldo:
print("Saldo insuficiente.")
return False
self.saldo -= valor
return True
def __str__(self):
return f"[{self.banco}] {self.titular}: R$ {self.saldo:.2f}"A classe completa: atributo de classe, __init__, depositar, sacar e __str__.
Repare em cada peça. O banco é um atributo de classe, igual para toda conta. O __init__ recebe titular e saldo (com padrão 0) e os guarda com self. Os métodos depositar e sacar primeiro validam o valor: nada de depósito ou saque com valor zero ou negativo, e nada de sacar mais do que há. Só depois eles mexem no saldo, e devolvem True ou False para avisar se deu certo. O __str__ monta a frase de exibição usando o banco, o titular e o saldo formatado.
Criando contas e operando
Com a classe pronta, criar contas é chamar ContaBancaria(...) com os dados. Cada objeto guarda o seu saldo, e os métodos alteram só o saldo do objeto em que são chamados. Vamos abrir duas contas, fazer depósitos e saques, e imprimir cada uma para ver o __str__ em ação. Acompanhe os comentários com a saída esperada e confira no Playground.
ana = ContaBancaria("Ana", 500)
bruno = ContaBancaria("Bruno") # saldo comeca em 0
ana.depositar(200)
ana.sacar(100)
bruno.depositar(50)
print(ana) # [ValorBank] Ana: R$ 600.00
print(bruno) # [ValorBank] Bruno: R$ 50.00
ana.sacar(5000) # Saldo insuficiente.
print(ana.saldo) # 600 (nao mudou)Duas contas independentes, operadas pelos métodos, e o saldo protegido pelas regras.
A conta da Ana começa com 500, recebe 200 e perde 100, terminando em 600. A do Bruno nasce com saldo 0 e chega a 50. Cada print mostra a conta por inteiro, graças ao __str__. O saque de 5000 na conta da Ana é barrado pela regra dentro de sacar, o saldo continua 600, e o programa segue sem erro. Isso é o objeto cuidando do próprio estado: as regras vivem dentro dele, e o resto do código só pede ações.
O que você construiu
Olhe para trás. Você começou o módulo com dados soltos e funções distantes, e termina com uma classe que junta tudo: os dados (titular, saldo), o comportamento (depositar, sacar), as regras que protegem o estado e uma exibição amigável. Esse é o núcleo da orientação a objetos, e ele reaparece o tempo todo em programas reais. Um carrinho de compras, um jogador, um pedido: todos seguem a mesma receita de atributos, métodos e uma boa representação.
Guarde a receita que você aplicou aqui, porque ela serve para qualquer classe nova. Primeiro, identifique a coisa e os seus dados, que viram atributos no __init__. Depois, liste as ações que ela sabe fazer, que viram métodos com self, cada um com as suas regras de validação. Por fim, ensine o objeto a se mostrar com um __str__ claro. Com isso, você tem uma classe sólida, fácil de usar e de ler. No próximo módulo, a orientação a objetos avança para herança e outros recursos, mas a base é esta que você acabou de construir.
Teste rápido
Na classe ContaBancaria, por que a validação do saque fica dentro do método sacar?
Perguntas frequentes
- Por que validar o valor antes de mexer no saldo?
- Para o objeto nunca entrar em um estado sem sentido, como saldo negativo ou depósito de valor negativo. A validação dentro do método garante que toda operação siga a regra, sem depender de quem chama. É o objeto protegendo os seus próprios dados.
- Por que os métodos devolvem True ou False?
- Para avisar quem chamou se a operação deu certo. Com esse retorno, o restante do programa pode reagir: confirmar a transação se veio True, ou pedir outro valor se veio False. Um método que só executa em silêncio deixa quem chama sem saber o resultado.
- O banco é atributo de classe. Toda conta mostra o mesmo?
- Sim. Como banco está no corpo da classe, todas as contas compartilham o mesmo valor, ValorBank, e o __str__ o exibe igual para todas. É o uso certo de atributo de classe: um dado igual para todas as instâncias, definido em um lugar só.
- Como eu guardaria um histórico de movimentos na conta?
- Criando self.movimentos = [] no __init__, uma lista por objeto, e dando append a cada depósito ou saque dentro dos métodos. É importante criar a lista no __init__, e não no corpo da classe, para cada conta ter o seu próprio histórico, sem vazar para as outras.
- Posso adicionar um método transferir?
- Pode, e é um ótimo exercício. Um transferir(self, destino, valor) usaria o próprio sacar para tirar desta conta e o depositar do destino para creditar. Reaproveitar os métodos que já validam mantém as regras em um lugar só e evita repetir a checagem.
- Essa classe está pronta para um sistema de banco real?
- Não. É um exemplo didático para fixar classes, métodos e __str__. Um sistema real precisa de segurança, registro de transações, tratamento de erros com exceções, persistência em banco de dados e muito mais. A base de orientação a objetos, porém, é exatamente esta que você praticou.
Fontes
Seu progresso fica salvo neste aparelho. Assinantes sincronizam entre os aparelhos.