Practicar la Herencia Múltiple
Python permite que una clase herede de más de una clase padre. Esto se denomina herencia múltiple. Puede ser una herramienta poderosa para combinar funcionalidades de diferentes fuentes, pero también introduce complejidad, particularmente en cómo Python decide qué método del padre usar si tienen el mismo nombre.
Este orden de búsqueda se denomina Orden de Resolución de Métodos (Method Resolution Order - MRO). Python utiliza un algoritmo llamado linealización C3 para determinar un MRO consistente y predecible.
Exploremos esto con un nuevo ejemplo. Abre el archivo multiple_inheritance.py desde el explorador de archivos y añade el siguiente 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 hereda de A, luego de B
class Child_AB(ParentA, ParentB):
pass
## Child hereda de B, luego 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()
## El método .mro() muestra el Orden de Resolución 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()])
Guarda el archivo. Aquí, Child_AB hereda de ParentA y luego de ParentB. Child_BA hereda en orden inverso. Cuando se llama a un método, Python lo busca en el orden especificado por el MRO.
Ejecuta el script desde la terminal:
python multiple_inheritance.py
Verás la siguiente salida:
--- 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 de la salida, puedes observar:
child1.speak() llama al método de ParentA porque ParentA aparece primero en el MRO de Child_AB.
child2.speak() llama al método de ParentB porque ParentB aparece primero en el MRO de Child_BA.
child2.common_method() llama a la versión definida directamente en Child_BA, ya que Python la encuentra allí primero antes de verificar a los padres.
Comprender el MRO es crucial para predecir el comportamiento en escenarios de herencia múltiple.