7.1 Método super()
Ya que hemos tocado el tema de la jerarquía de herencia, será útil hablar sobre los matices de trabajar con campos y métodos de la clase base. Para esto, en Python hay un método super() especial. Este método se utiliza para llamar a métodos de la clase base dentro de una clase hija.
Tiene tres áreas principales de aplicación:
Llamada a métodos de la clase padre:
El método super() permite llamar a un método de la clase padre desde la clase hija, sin indicar explícitamente el nombre de la clase padre. Esto es especialmente útil al trabajar con herencia múltiple y ayuda a evitar errores al cambiar la jerarquía de clases.
Inicialización de clases base:
super() se usa a menudo en el constructor de la clase hija para llamar al constructor de la clase base, lo que permite inicializar atributos de la clase base en la clase hija.
Soporte de herencia múltiple:
En caso de herencia múltiple, super() resuelve correctamente el orden de llamadas a métodos (MRO, Method Resolution Order), lo que hace preferible su uso frente a la llamada explícita de métodos de clases padre. Hablaremos de esto un poco más tarde.
7.2 Constructor de la clase base
El constructor de la clase base debe ser llamado explícitamente. Parece que ocurre automáticamente, pero en realidad no es así. Los constructores de clases base siempre deben ser llamados explícitamente, ya que muy a menudo se necesita pasarles argumentos especiales.
Ejemplo:
class Animal:
def __init__(self, type, name):
self.type = type
self.name = name
class Dog(Animal):
def __init__(self, name):
super().__init__("Perro", name) # Llamada al constructor de la clase base
class Cat(Animal):
def __init__(self, name):
super().__init__("Gato", name) # Llamada al constructor de la clase base
# Creación del objeto Dog
dog = Dog("Buddy")
print(dog)
En este ejemplo, el constructor de la clase base (Animal) tiene dos parámetros: tipo de animal y su nombre. Y las clases derivadas solo tienen uno, solo el nombre.
Es en los constructores de las clases Dog y Cat donde se decide qué pasar al constructor de la clase base: los nombres de los tipos de animales «Perro» y «Gato».
Así que:
- El constructor de la clase base debe ser llamado en el constructor de la clase hija.
- Para esto se debe usar el método
super(). - Pasar el parámetro
selfpor separado no es necesario — Python lo añadirá automáticamente al llamar al método.
7.3 Uso del método super()
El método super() en Python se puede usar no solo en constructores, sino también en otros métodos de clases para llamar a métodos de la clase padre. Esto puede ser útil cuando es necesario ampliar o modificar el comportamiento de un método definido en la clase padre.
Echemos un vistazo a algunos ejemplos:
Llamada al método de la clase padre en un método hijo
En este ejemplo, el método speak() en la clase Dog primero llama al método speak() de la clase Animal usando super(), y luego añade su propio comportamiento.
class Animal:
def speak(self):
return "Some generic animal sound"
class Dog(Animal):
def speak(self):
parent_speech = super().speak() # Llamada al método de la clase padre
return f"{parent_speech} And the dog barks!"
dog = Dog()
print(dog.speak()) # Imprimirá: Some generic animal sound And the dog barks!
Llamada al método de la clase padre para comprobar el estado
En este ejemplo, el método check_health() en la clase Dog llama al método check_health() de la clase Animal para añadir comprobaciones adicionales.
class Animal:
def check_health(self):
return "Animal is healthy"
class Dog(Animal):
def check_health(self):
parent_check = super().check_health() # Llamada al método de la clase padre
return f"{parent_check}. Dog needs a walk!"
dog = Dog()
print(dog.check_health()) # Imprimirá: Animal is healthy. Dog needs a walk!
Llamada al método de la clase padre en un método que modifica el estado
En este ejemplo, el método withdraw() en la clase SavingsAccount primero comprueba si se ha excedido el límite de retiro, y si no, llama al método withdraw() de la clase BankAccount para realizar la operación.
class BankAccount:
def __init__(self, balance):
self.balance = balance
def withdraw(self, amount):
if self.balance >= amount:
self.balance -= amount
return f"Withdrew {amount}. New balance: {self.balance}"
return "Insufficient funds"
class SavingsAccount(BankAccount):
def withdraw(self, amount):
if amount > 1000:
return "Withdrawal limit exceeded"
return super().withdraw(amount) # Llamada al método de la clase padre
savings = SavingsAccount(1500)
print(savings.withdraw(500)) # Imprimirá: Withdrew 500. New balance: 1000
print(savings.withdraw(1500)) # Imprimirá: Withdrawal limit exceeded
GO TO FULL VERSION