Intermediário 8 min de leitura 01/08/2026

Programação Orientada a Objetos sem mistério

Classes, herança e encapsulamento construindo um sistema de biblioteca do zero

POO assusta muita gente no começo por causa dos termos — classe, objeto, herança, encapsulamento. Mas a ideia central é simples: agrupar dados e comportamento num mesmo lugar. Vamos construir um sistema de biblioteca do zero para mostrar como isso funciona na prática.

O problema que POO resolve

Imagine representar 3 livros sem POO:

livro1_titulo = "O Senhor dos Anéis"
livro1_autor = "Tolkien"
livro1_disponivel = True

livro2_titulo = "1984"
livro2_autor = "Orwell"
livro2_disponivel = False

Isso fica incontrolável rápido. A solução é criar um molde que define como cada livro se parece — isso é uma classe.

Criando sua primeira classe

class Livro:
    def __init__(self, titulo, autor):
        self.titulo = titulo
        self.autor = autor
        self.disponivel = True

    def emprestar(self):
        if self.disponivel:
            self.disponivel = False
            return f'"{self.titulo}" emprestado com sucesso.'
        return f'"{self.titulo}" já está emprestado.'

    def devolver(self):
        self.disponivel = True
        return f'"{self.titulo}" devolvido. Obrigado!'

Dois conceitos aqui:

  • __init__ é o construtor — roda automaticamente quando você cria um objeto
  • self é a referência ao próprio objeto — é como ele sabe a diferença entre meus dados e os dados de outro livro

Criando objetos a partir da classe

livro1 = Livro("O Senhor dos Anéis", "Tolkien")
livro2 = Livro("1984", "Orwell")

print(livro1.emprestar())  # "O Senhor dos Anéis" emprestado com sucesso.
print(livro1.emprestar())  # "O Senhor dos Anéis" já está emprestado.
print(livro1.devolver())   # "O Senhor dos Anéis" devolvido. Obrigado!

Herança: reaproveitar sem repetir

E se quisermos um tipo especial de livro — um e-book, que não tem exemplar físico e nunca fica "indisponível"? Herança permite criar uma classe nova que aproveita tudo da anterior e só muda o que precisa.

class Ebook(Livro):
    def __init__(self, titulo, autor, formato):
        super().__init__(titulo, autor)
        self.formato = formato

    def emprestar(self):
        # E-book pode ser "emprestado" por múltiplas pessoas
        return f'"{self.titulo}" ({self.formato}) disponível para download.'
epub = Ebook("Python Fluente", "Ramalho", "EPUB")
print(epub.emprestar())  # "Python Fluente" (EPUB) disponível para download.
print(epub.autor)        # Ramalho  ← herdado de Livro

Encapsulamento: proteger o estado interno

Em Python, o convênio é usar underscore para sinalizar que um atributo é interno e não deve ser acessado diretamente de fora:

class ContaBancaria:
    def __init__(self, saldo_inicial):
        self._saldo = saldo_inicial  # _ = "use com cuidado"

    def depositar(self, valor):
        if valor > 0:
            self._saldo += valor

    def sacar(self, valor):
        if valor > self._saldo:
            return "Saldo insuficiente."
        self._saldo -= valor
        return f"Saque de R${valor:.2f} realizado."

    @property
    def saldo(self):
        return self._saldo
conta = ContaBancaria(1000)
conta.depositar(500)
print(conta.sacar(200))   # Saque de R$200.00 realizado.
print(conta.saldo)        # 1300
O @property cria um getter — permite ler conta.saldo como se fosse um atributo normal, mas por baixo é um método. Útil para validar leitura ou calcular um valor na hora.

Desafio rápido

  1. Crie uma classe Aluno com nome, nota1 e nota2. Adicione um método media() que retorna a média e um método aprovado() que retorna True se a média for maior ou igual a 6.
  2. Crie 3 instâncias e imprima o status de aprovação de cada uma.

Próximos passos

Com POO, você tem as ferramentas para organizar qualquer programa de médio porte. O próximo tutorial aplica tudo isso no mundo real: vamos construir uma API REST com Django.