La herencia es uno de los pilares fundamentales de la programación orientada a objetos. Permite crear nuevas clases basadas en clases existentes, heredando atributos y métodos. A la clase original se le conoce como clase padre o superclase, y a la clase derivada se le llama clase hija o subclase.
Este mecanismo facilita la reutilización de código y la creación de jerarquías más organizadas, siguiendo el principio DRY (Don't Repeat Yourself), que promueve evitar la duplicación innecesaria de código.
class Animal:
def __init__(self, especie, edad):
self.especie = especie
self.edad = edad
def describeme(self):
print(f"Soy un {self.especie} y tengo {self.edad} años.")
Ahora podemos definir una subclase que hereda de Animal
:
class Perro(Animal):
pass
La clase Perro
ahora posee todos los atributos y métodos de Animal
, aunque no hayamos definido nada dentro de ella.
¿Por qué utilizar herencia?
La herencia permite modelar relaciones jerárquicas entre entidades. Por ejemplo, en lugar de definir múltiples clases para cada tipo de animal duplicando código, podemos centralizar lo común en una clase Animal y extenderla:
- Evita la duplicación de código.
- Promueve la reutilización y facilita el mantenimiento.
- Permite extender el comportamiento de clases existentes.
Una subclase puede:
- Heredar atributos y métodos de su clase padre.
- Sobreescribir métodos o atributos heredados para cambiar su comportamiento.
- Agregar nuevos atributos o métodos propios.
Herencia simple:
La herencia simple ocurre cuando una subclase hereda de una sola clase base. Sigamos con el ejemplo:
class Perro(Animal):
def hablar(self):
print("¡Guau!")
def moverse(self):
print("Camino en cuatro patas.")
También podríamos tener una clase Abeja
que herede de Animal
pero añada su propio comportamiento:
class Abeja(Animal):
def hablar(self):
print("Bzzz")
def moverse(self):
print("Vuelo")
def picar(self):
print("¡Pico con mi aguijón!")
En este caso:
describeme()
es heredado directamente.hablar()
ymoverse()
son sobreescritos.picar()
es un nuevo método exclusivo deAbeja
.
Herencia múltiple:
Python permite que una clase herede de más de una clase base. Esto se conoce como herencia múltiple:
class Clase1:
def metodo(self):
print("Método de Clase1")
class Clase2:
def metodo(self):
print("Método de Clase2")
class Clase3(Clase1, Clase2):
pass
obj = Clase3()
obj.metodo() # Salida: "Método de Clase1"
¿Por qué Clase1.metodo()
y no Clase2.metodo()
? Aquí entra en juego el MRO(Method Resolution Order).
MRO: Method Resolution Order
El MRO es el orden en el que Python busca métodos y atributos en las clases cuando hay herencia múltiple. Se puede consultar con:
print(Clase3.__mro__)
Esto devuelve una tupla con el orden de búsqueda. Python sigue el algoritmo C3 Linearization, y busca de izquierda a derecha.
Nota: Todas las clases en Python heredan, directa o indirectamente, de la clase base object
, que aparece al final del MRO.