Saltar al contenido principal
eLearner.app
Módulo 7 · Lección 2 de 426/36 en el curso~12 min
Lecciones del módulo (2/4)

Herencia

La herencia (inheritance) permite crear una nueva clase (la subclase) que hereda los atributos y métodos de una clase existente (la clase base), y puede extenderlos o sobrescribirlos (override).

Sintaxis básica

Python
class Animale:
    def __init__(self, nome):
        self.nome = nome

    def saluta(self):
        return f"{self.nome} fa un verso"

class Cane(Animale):       # Cane HEREDA de Animale
    def saluta(self):       # SOBRESCRITURA del método (override)
        return f"{self.nome} dice WOOF!"

a = Animale("X")
c = Cane("Fido")
a.saluta()      # 'X fa un verso'
c.saluta()      # 'Fido dice WOOF!'

Cane hereda __init__ de Animale sin necesidad de volver a escribirlo.

super(): llamar al método base

Cuando quieres extender un método base (no reemplazarlo por completo), usa super():

Python
class Animale:
    def __init__(self, nome):
        self.nome = nome

class Cane(Animale):
    def __init__(self, nome, razza):
        super().__init__(nome)    # delega a la clase base
        self.razza = razza

c = Cane("Fido", "Labrador")
c.nome        # 'Fido'
c.razza       # 'Labrador'

isinstance: comprobación de tipo

Python
isinstance(c, Cane)        # True
isinstance(c, Animale)     # True (también la clase base)
isinstance(c, str)         # False

isinstance(x, ClaseBase) también reconoce a todas las subclases: esto es lo que hace que la herencia sea útil para el polimorfismo.

Python
animali = [Cane("Fido", "X"), Animale("Pippo")]
for a in animali:
    print(a.saluta())        # cada objeto responde a su manera

MRO (Method Resolution Order) — resumen

Cuando tienes herencia múltiple, Python decide en qué orden buscar un método siguiendo el MRO, calculado con el algoritmo C3. Para el 95% de los casos basta con saber:

  1. busca primero en la instancia,
  2. luego en su clase,
  3. luego en las clases base en el orden de declaración.
Python
Cane.__mro__
# (<class 'Cane'>, <class 'Animale'>, <class 'object'>)

object es la raíz de todas las clases en Python 3.

Pruébalo tú

Ejercicio#python.m7.l2.e1
Intentos: 0Cargando...

Dada `class Vehicle: def __init__(self, brand): self.brand = brand`, define `Car(Vehicle)` con __init__(self, brand, model) que llame a super().__init__ y guarde self.model. Crea `a = Car('Fiat', '500')` y evalúa `(a.brand, a.model)`.

Cargando editor...
Mostrar pista

super().__init__(brand) y luego self.model = model.

Solución disponible después de 3 intentos

Ejercicio de repaso

Ejercicio#python.m7.l2.e2
Intentos: 0Cargando...

Define `class Shape: def area(self): return 0` y `class Square(Shape)` con __init__(self, side) y area() que devuelva side * side. Crea `q = Square(5)` y evalúa la tupla `(q.area(), isinstance(q, Shape))`.

Cargando editor...
Mostrar pista

self.side * self.side.

Solución disponible después de 3 intentos

Desafío adicional

Ejercicio#python.m7.l2.e3
Intentos: 0Cargando...

Crea una clase `Square` que herede de la clase `Rectangle` (definida a continuación). El constructor de `Square` debe tomar un único parámetro `side` y pasarlo a `super().__init__(side, side)`. Instancia un cuadrado con lado `6` en `sq` y evalúa `sq.area()`.

Cargando editor...
Mostrar pista

Declara la clase Square(Rectangle): y llama a super().__init__(side, side) en el constructor.

Solución disponible después de 3 intentos