Módulo 10 - Orientação a objetos avançada

Herança múltipla e a ordem de resolução

10 min de leitura · por Cesar Gargiulo, revisado pela equipe ValorFinal e GuardiaSec · Atualizado em 01/07/2026

O que você vai aprender

  • Entender herança múltipla e o problema do diamante.
  • Ler a MRO de uma classe com __mro__.
  • Usar super() como o próximo da cadeia, não só o pai.
  • Reconhecer mixins como uso saudável de herança múltipla.

Herdar de várias classes

Diferente de várias linguagens, o Python permite herança múltipla: uma classe pode ter mais de uma base. Você escreve class Anfibio(Terrestre, Aquatico) e a nova classe herda de ambas. Isso é poderoso, mas abre uma pergunta incômoda. Se tanto Terrestre quanto Aquatico definem um método mover, qual deles a classe Anfibio usa? E se as duas, por sua vez, herdam de uma base comum, digamos Animal, quantas vezes o construtor de Animal roda? Esse emaranhado é o famoso problema do diamante, pelo formato do diagrama de herança. O Python resolve tudo isso com uma regra clara e determinística, a ordem de resolução de métodos.

A MRO é a lista ordenada das classes em que o Python procura um método, da mais específica para a mais geral. Quando você chama um método em um objeto, o Python percorre essa lista e usa a primeira classe que o define. Você pode ver a MRO de qualquer classe: ela está no atributo __mro__ ou no método mro(). Ler essa lista é a forma definitiva de entender por que um método específico foi escolhido, sem adivinhação. A ordem não é aleatória; ela segue um algoritmo que respeita a ordem em que você declarou as bases e garante que cada classe apareça uma única vez.

Lendo a MRO

Ver a MRO na prática dissolve o mistério. No exemplo, D herda de B e C, que herdam de A. A MRO resultante é D, depois B, depois C, depois A e por fim object, a base de tudo. Quando você chama um método em um objeto D, o Python procura nessa ordem e para na primeira classe que o tem. Repare que A, a base comum, aparece uma única vez, no fim, mesmo sendo ancestral de B e de C. É essa garantia que resolve o problema do diamante: nenhuma classe é visitada duas vezes, então a base comum roda uma vez só, não uma por caminho.

class A:
    def quem(self):
        return "A"

class B(A):
    def quem(self):
        return "B"

class C(A):
    def quem(self):
        return "C"

class D(B, C):
    pass

print([cls.__name__ for cls in D.__mro__])
# ['D', 'B', 'C', 'A', 'object']
print(D().quem())   # B  (primeira da MRO que define quem)

A MRO de D é D, B, C, A, object. A base comum A aparece uma única vez, no fim.

super() é o próximo da cadeia

Aqui está a peça que confunde quase todo mundo. Muita gente aprende super() como uma forma de chamar a classe pai, e em herança simples é isso mesmo. Mas com herança múltipla a definição correta é outra: super() chama o próximo método na MRO, que nem sempre é o pai declarado. Isso é o que torna a herança cooperativa possível. Quando cada classe da hierarquia chama super() no seu método, o Python vai encadeando as chamadas ao longo da MRO, e cada classe contribui com a sua parte uma única vez. É assim que um construtor consegue inicializar todas as bases sem repetir a base comum, respeitando o diamante.

class Base:
    def __init__(self):
        print("Base")

class Esquerda(Base):
    def __init__(self):
        print("Esquerda")
        super().__init__()   # proximo da MRO, nao "o pai"

class Direita(Base):
    def __init__(self):
        print("Direita")
        super().__init__()

class Junta(Esquerda, Direita):
    def __init__(self):
        print("Junta")
        super().__init__()

Junta()
# Junta / Esquerda / Direita / Base
# Base roda UMA vez, gracas a MRO e ao super() cooperativo

Cada __init__ chama super(); a cadeia segue a MRO e Base roda uma única vez.

O uso mais saudável e comum de herança múltipla são os mixins. Um mixin é uma classe pequena, feita para ser misturada a outras, que acrescenta um comportamento bem definido sem representar uma entidade completa. Uma classe SerializavelJsonMixin que dá o método para virar JSON, uma LogavelMixin que acrescenta registro de eventos. Você combina esses comportamentos com a classe principal por herança múltipla, e cada mixin contribui com sua fatia. Quando a herança múltipla vira mixins de comportamento, e não uma tentativa de modelar uma coisa que é várias coisas ao mesmo tempo, ela fica clara e fácil de manter.

Teste rápido

Em herança múltipla, o que super() chama de verdade?

Perguntas frequentes

O que é o problema do diamante?
É o cenário em que uma classe herda de duas que, por sua vez, herdam de uma base comum, formando um diagrama em losango. A dúvida é qual método vale em caso de conflito e quantas vezes a base comum é inicializada. A MRO do Python resolve isso visitando cada classe uma única vez, em ordem determinística.
Como vejo a ordem de resolução de uma classe?
Use Classe.__mro__ ou Classe.mro(), que devolvem a lista das classes na ordem de busca, da mais específica para a mais geral, terminando em object. Ler essa lista é a forma definitiva de entender por que um método foi escolhido, sem depender de intuição sobre a hierarquia.
A ordem em que listo as bases muda o comportamento?
Muda. Em class D(B, C), a MRO prefere B a C, então o método de B vence quando ambos definem o mesmo nome. Inverter para class D(C, B) inverte a preferência. Por isso a ordem das bases é uma decisão de projeto que afeta qual versão de cada método a sua classe usa.
Por que sempre chamar super() nos métodos das bases?
Porque é o super() em cada classe que encadeia as chamadas ao longo da MRO, garantindo que cada uma contribua sua parte uma vez. Se uma classe da cadeia esquecer o super(), ela interrompe o encadeamento e classes seguintes deixam de ser inicializadas, um bug sutil em hierarquias com herança múltipla.
Herança múltipla é sempre uma má ideia?
Não, desde que usada com critério. A forma saudável são os mixins: classes pequenas de comportamento, combinadas com a classe principal. O que costuma dar errado é tentar modelar, por herança múltipla, algo que seria melhor por composição. A próxima aula trata justamente de quando preferir composição a herança.

Fontes

Seu progresso fica salvo neste aparelho. Assinantes sincronizam entre os aparelhos.