Médio Python

Herança múltipla e MRO

Enunciado

Crie duas classes A e B, ambas com método quem_sou(). A retorna "A", B retorna "B". Depois crie C(A, B) que sobrescreve quem_sou() chamando super().quem_sou() e adicionando "C". Imprima o resultado de C().quem_sou() e a MRO de C.

Requisitos

  • A.quem_sou() retorna "A"; B.quem_sou() retorna "B".
  • C herda de A e B nessa ordem.
  • C.quem_sou() usa super().quem_sou() e retorna a string concatenada com "C".
  • Imprimir C().quem_sou() e C.mro().

Código inicial

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

class B:
    def quem_sou(self):
        return "B"

class C(A, B):
    def quem_sou(self):
        # complete
        pass

# teste
print(C().quem_sou())
print(C.mro())

Saída esperada

AC
[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]
Ver dica

A MRO de C(A, B) é C, A, B, object. super() em C chama o próximo na MRO, que é A.

Mostrar solução
class A:
    def quem_sou(self):
        return "A"


class B:
    def quem_sou(self):
        return "B"


class C(A, B):
    def quem_sou(self):
        # super() segue a MRO: C -> A -> B -> object
        return super().quem_sou() + "C"


if __name__ == "__main__":
    print(C().quem_sou())
    print(C.mro())

Passo a passo

  1. Definimos A e B, cada uma com quem_sou() retornando sua letra.
  2. C herda de A e B na ordem (A, B). A MRO será C, A, B, object.
  3. Em C.quem_sou(), super() não se refere apenas a A, mas ao próximo na MRO, que é A.
  4. A.quem_sou() retorna "A"; concatenamos "C" e obtemos "AC".
  5. Imprimimos o resultado e a MRO, que mostra a ordem linear de busca.

Por que funciona

A MRO garante que métodos sejam resolvidos de forma consistente em herança múltipla. super() respeita essa ordem, permitindo que cada classe na cadeia contribua sem chamadas explícitas. Isso evita o problema do diamante e mantém a cooperação entre classes.

Erros comuns

  • Chamar A.quem_sou(self) diretamente: funciona, mas ignora a MRO e pode pular B em cenários mais complexos.
  • Ordem de herança trocada (class C(B, A)): a MRO muda e o resultado seria "BC".
  • Esquecer de retornar em C.quem_sou(): o método retorna None e a concatenação falha.

Outra forma de resolver

Poderíamos usar super(C, self).quem_sou(), que é equivalente a super().quem_sou() dentro de C. A forma sem argumentos é preferível por ser mais curta e menos propensa a erros.

Saída esperada

AC
[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]