Orientação a objetos em Python: guia completo para concursos
Seja para as carreiras de Tecnologia da Informação ou para cargos que exigem Ciência de Dados, Python deixou de ser um diferencial para se tornar um requisito básico. É necessário conhecer diversos aspectos da linguagem. Orientação a objetos está entre os tópicos mais cobrados nas questões sobre Python nos concursos públicos mais recentes.
Neste artigo, vamos abordar os seguintes tópicos:
- O que é o paradigma orientado a objetos
- Como definir classes e instanciar objetos em Python
- O método construtor __init__ e os atributos de instância
- Herança simples e múltipla
- Polimorfismo e sobrescrita de métodos
- Métodos especiais (dunder methods)
- Questões comentadas no estilo de prova

O paradigma orientado a objetos
A orientação a objetos é um paradigma de programação que organiza o código em torno de objetos, que representam entidades do mundo real com características e comportamentos. Ela também é chamada de POO.
Python é uma linguagem que suporta POO, além de outros paradigmas. Isso significa que você pode escrever código orientado a objetos sem nenhuma obrigatoriedade de estrutura rígida, como ocorre em outras linguagens, a exemplo de Java.
Os quatro pilares da programação orientada a objetos são:
| Pilar | Descrição |
| Encapsulamento | Agrupa dados e comportamentos em uma única unidade (a classe) |
| Herança | Permite que uma classe herde atributos e métodos de outra |
| Polimorfismo | Um mesmo método se comporta de forma diferente conforme a classe |
| Abstração | Expõe apenas o necessário, ocultando a implementação interna |
Classes e objetos em Python
Uma classe é como uma planta baixa: ela define a estrutura contendo atributos e métodos. Porém, por si só, não realiza ações, e é uma abstração que precisa tomar forma. O objeto (ou instância) é a realização concreta dessa planta.
Em Python, definimos uma classe com a palavra-chave class:
class Animal:
def __init__(self, nome, som):
self.nome = nome
self.som = som
def falar(self):
print(f”{self.nome} faz: {self.som}”)
cachorro = Animal(“Rex”, “Au Au”)
cachorro.falar() # Rex faz: Au Au
Veja que a classe precisa ser instanciada para poder executar ações. Python possui uma peculiaridade: o parâmetro self é obrigatório em todos os métodos de instância. Ele representa o próprio objeto e permite o acesso aos seus atributos internos.
O método init e os atributos de instância
O método __init__ é o construtor da classe em Python. Construtores são chamados automaticamente sempre que uma nova instância é criada. Dentro deles, declaramos os atributos de instância, que são próprios de cada objeto.
Observe o exemplo abaixo, no estilo das questões cobradas em provas:
class Teste:
a = 4
def __init__(self, x, y, z):
self.a = x + y + z
x = Teste(1, 2, 10)
y = getattr(x, ‘a’)
setattr(x, ‘a’, y * 2)
print(x.a)
A saída desse código é 26. O __init__ define self.a = 1+2+10 = 13. Em seguida, getattr recupera esse valor (y = 13) e setattr o redefine para y * 2 = 26.
As funções getattr e setattr são usadas para acessar e modificar atributos dinamicamente, o que é um recurso bastante característico de Python.
Herança em Python
A herança permite que uma classe (denominada subclasse) reaproveite o código de outra (denominada superclasse). Em Python, a sintaxe é direta:
class Veiculo:
def __init__(self, modelo):
self.modelo = modelo
def mover(self):
print(f”{self.modelo} se move.”)
class Carro(Veiculo):
def mover(self):
print(f”{self.modelo} Anda!”)
class Aviao(Veiculo):
def mover(self):
print(f”{self.modelo} Voa!”)
Ao chamar mover() em cada objeto, cada classe executa sua própria versão do método. Isso é polimorfismo, o que veremos a seguir.
Python também suporta herança múltipla, em que uma classe pode herdar de duas ou mais superclasses simultaneamente. Essa é uma diferença importante em relação a Java, que não permite herança múltipla direta de classes.
class A:
def metodo(self):
print(“Método de A”)
class B:
def outro(self):
print(“Método de B”)
class C(A, B):
pass
A ordem em que as classes são listadas afeta a resolução de métodos, regida pelo algoritmo MRO (Method Resolution Order), consultável via C.__mro__.
Polimorfismo e sobrescrita de métodos
Polimorfismo é a capacidade de um método se comportar de formas diferentes dependendo da classe do objeto. Em Python, isso ocorre de forma natural por meio da sobrescrita de métodos (override).
Observe o seguinte código, que frequentemente aparece em provas:
veiculos = [
Carro(“Ibiza Touring 2.0”),
Aviao(“Boeing 747”),
Carro(“Ford Mustang”)
]
for v in veiculos:
v.mover()
A saída será:
Ibiza Touring 2.0 Anda!
Boeing 747 Voa!
Ford Mustang Anda!
Cada objeto responde à mesma chamada mover() de acordo com sua própria implementação. Esse é o comportamento polimórfico em ação.
Métodos especiais (dunder methods)
Os métodos dunder (do inglês double underscore) são métodos especiais em Python que começam e terminam com dois sublinhados, como __init__, __str__, __len__ e __repr__.
Eles permitem personalizar o comportamento de operadores e funções nativas sobre os objetos da sua classe. Veja um exemplo:
class Produto:
def __init__(self, nome, preco):
self.nome = nome
self.preco = preco
def __str__(self):
return f”{self.nome} – R$ {self.preco:.2f}”
p = Produto(“Notebook”, 3500.00)
print(p) # Notebook – R$ 3500.00
Sem definir o método __str__, a chamada print(p) exibiria algo como <__main__.Produto object at 0x…>. É importante não confundir dunder methods com atributos “privados”:
- __nome__ (dois sublinhados em cada lado): método especial/mágico
- __nome (dois sublinhados apenas no início): convenção usada para tornar atributos não acessíveis fora da classe
- _nome (um sublinhado): convenção usada para deixar o atributo acessível somente dentro de um módulo Python
Diferenças entre Python e Java na orientação a objetos
As bancas frequentemente comparam Python e Java em questões de orientação a objetos. A tabela abaixo resume os pontos mais cobrados:
| Característica | Python | Java |
| Tipagem | Dinâmica (não exige declaração de tipo) | Estática (tipos declarados explicitamente) |
| Herança múltipla | Suportada diretamente | Não permitida entre classes (apenas interfaces) |
| Construtor | __init__ | Método com mesmo nome da classe |
| Modificadores de acesso | Convenção (_ e __) | public, private, protected |
| Obrigatoriedade da classe | Não obrigatória | Todo código deve estar dentro de uma classe |
Questão comentada
Analise a questão a seguir:
Durante o desenvolvimento de um sistema de atendimento ao cliente, a equipe adotou o paradigma orientado a objetos com partes do código em Java e Python. Julgue: “Em Python, diferentemente de em Java, não é necessário declarar os tipos dos parâmetros de métodos e funções, o que caracteriza uma tipagem dinâmica e flexível.”
Gabarito: Certo.
A afirmativa está correta. Python usa tipagem dinâmica: o tipo da variável é inferido em tempo de execução, sem necessidade de declaração explícita. Java, por outro lado, exige que o tipo seja declarado na assinatura do método.
Conclusão
Orientação a objetos em Python é um tema de alto índice de cobrança em concursos de TI. O domínio de classes, herança, polimorfismo e métodos especiais é absolutamente necessário para acertar as questões.
https://www.geeksforgeeks.org/python/class-instance-attributes-python
https://realpython.com/python3-object-oriented-programming
https://medium.com/@ruitcatarino/understanding-pythons-method-resolution-order-mro-f7cbcec36993