Praticar Herança Múltipla
Python permite que uma classe herde de mais de uma classe pai. Isso é chamado de herança múltipla (multiple inheritance). Pode ser uma ferramenta poderosa para misturar funcionalidades de diferentes fontes, mas também introduz complexidade, particularmente na forma como o Python decide qual método do pai usar se eles tiverem o mesmo nome.
Essa ordem de busca é chamada de Ordem de Resolução de Métodos (Method Resolution Order - MRO). Python usa um algoritmo chamado linearização C3 para determinar um MRO consistente e previsível.
Vamos explorar isso com um novo exemplo. Abra o arquivo multiple_inheritance.py no explorador de arquivos e adicione o seguinte código:
## File: multiple_inheritance.py
class ParentA:
def speak(self):
print("Speaking from ParentA")
def common_method(self):
print("ParentA's common method")
class ParentB:
def speak(self):
print("Speaking from ParentB")
def common_method(self):
print("ParentB's common method")
## Child herda de A, depois de B
class Child_AB(ParentA, ParentB):
pass
## Child herda de B, depois de A
class Child_BA(ParentB, ParentA):
def common_method(self):
print("Child_BA's own common method")
if __name__ == "__main__":
child1 = Child_AB()
child2 = Child_BA()
print("--- Investigating Child_AB (ParentA, ParentB) ---")
child1.speak()
child1.common_method()
## O método .mro() mostra a Ordem de Resolução de Métodos
print("MRO for Child_AB:", [c.__name__ for c in Child_AB.mro()])
print("\n--- Investigating Child_BA (ParentB, ParentA) ---")
child2.speak()
child2.common_method()
print("MRO for Child_BA:", [c.__name__ for c in Child_BA.mro()])
Salve o arquivo. Aqui, Child_AB herda de ParentA e depois de ParentB. Child_BA herda na ordem inversa. Quando um método é chamado, o Python o procura na ordem especificada pelo MRO.
Execute o script no terminal:
python multiple_inheritance.py
Você verá a seguinte saída:
--- Investigating Child_AB (ParentA, ParentB) ---
Speaking from ParentA
ParentA's common method
MRO for Child_AB: ['Child_AB', 'ParentA', 'ParentB', 'object']
--- Investigating Child_BA (ParentB, ParentA) ---
Speaking from ParentB
Child_BA's own common method
MRO for Child_BA: ['Child_BA', 'ParentB', 'ParentA', 'object']
A partir da saída, você pode observar:
child1.speak() chama o método de ParentA porque ParentA vem primeiro no MRO de Child_AB.
child2.speak() chama o método de ParentB porque ParentB vem primeiro no MRO de Child_BA.
child2.common_method() chama a versão definida diretamente em Child_BA, pois o Python a encontra lá primeiro antes de verificar os pais.
Compreender o MRO é crucial para prever o comportamento em cenários de herança múltipla.