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".Cherda deAeBnessa ordem.C.quem_sou()usasuper().quem_sou()e retorna a string concatenada com"C".- Imprimir
C().quem_sou()eC.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
- Definimos
AeB, cada uma comquem_sou()retornando sua letra. Cherda deAeBna ordem(A, B). A MRO seráC, A, B, object.- Em
C.quem_sou(),super()não se refere apenas aA, mas ao próximo na MRO, que éA. A.quem_sou()retorna"A"; concatenamos"C"e obtemos"AC".- 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 pularBem 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 retornaNonee 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'>]