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.

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.