¿Te resulta más fácil leer con fondo crema, un tono de color, más contraste o un texto más grande? Elige tus colores y tu texto una sola vez, para todas las páginas.

Lección gratuita

Herencia y polimorfismo en Python

Después de esta lección: Puedo reutilizar código con la herencia y usar el polimorfismo.

Lección de 65 min6 comandosLaboratorio de comandos de Linux de cada día: los treinta comandos que se escriben de memoria

Tres entradas de cine con una sola base

La herencia deja que una clase nueva reutilice los atributos y métodos de otra. El polimorfismo deja llamar al mismo método sobre objetos distintos, y cada uno responde a su manera.

Un cine vende entrada normal, de estudiante y VIP. Las tres tienen precio, pero lo calculan distinto. Con herencia escribes lo común una vez y solo cambias lo que difiere.

Al final de esta lección

Nota

Puedo reutilizar código con la herencia y usar el polimorfismo.

Palabras clave

PalabraQué significaEjemplo
Herenciauna clase recibe los atributos y métodos de otra
Superclasela clase de la que se hereda
Subclasela clase que hereda de otraclass EntradaVip(Entrada)
Sobrescribirdar a un método heredado un cuerpo nuevo
Polimorfismola misma llamada hace cosas distintas según el objeto
super()da acceso a la versión de la superclase

Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.

Una subclase hereda lo de su superclase

Se escribe la superclase entre paréntesis: class EntradaVip(Entrada). La subclase tiene todos los atributos y métodos de Entrada sin copiarlos.

Heredar es decir «es un tipo de». Una entrada VIP es un tipo de entrada. Por eso puede ir en cualquier sitio donde se espere una entrada.

Ejemplo: qué hereda y qué cambia cada clase

ClaseQué heredaQué cambiaPrecio con base de 10 €
EntradaNada, es la baseDevuelve el precio base10 €
EntradaEstudianteEl constructorResta 3 € al precio7 €
EntradaVipEl método precioSuma 4 € y guarda la bebida14 €

Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.

Sobrescribir cambia un método; super() lo amplía

Si la subclase define un método con el mismo nombre, sobrescribe el de la superclase. Python usa el de la subclase.

A veces quieres el resultado original y algo más. super().precio() llama al método de la superclase. En EntradaVip, el precio es el de la entrada más 4 euros.

Tres clases y un mismo método

Código: python
# El cine vende tres tipos de entrada.
class Entrada:
    def __init__(self, precio_base):
        self.precio_base = precio_base

    def precio(self):
        return self.precio_base

class EntradaEstudiante(Entrada):
    def precio(self):
        return self.precio_base - 3

class EntradaVip(Entrada):
    def __init__(self, precio_base, bebida):
        super().__init__(precio_base)
        self.bebida = bebida

    def precio(self):
        return super().precio() + 4

for entrada in [Entrada(10), EntradaEstudiante(10), EntradaVip(10, "zumo")]:
    print(entrada.precio())
# Cambia el descuento del estudiante a 4 euros y vuelve a ejecutar.

Guarda la familia de entradas en un archivo

En el laboratorio guardas la familia de clases en entradas.py. Luego la usas desde otro archivo, taquilla.py, que suma todas las entradas de una venta.

Antes de pulsar Ejecutar, predice qué imprimirá cada orden. Después compara.

Entra en la carpeta de trabajo

Comando
mkdir -p ~/oop && cd ~/oop

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Escribe las tres clases en un archivo

Comando
printf 'class Entrada:\n    def __init__(self, precio_base):\n        self.precio_base = precio_base\n\n    def precio(self):\n        return self.precio_base\n\n\nclass EntradaEstudiante(Entrada):\n    def precio(self):\n        return self.precio_base - 3\n\n\nclass EntradaVip(Entrada):\n    def __init__(self, precio_base, bebida):\n        super().__init__(precio_base)\n        self.bebida = bebida\n\n    def precio(self):\n        return super().precio() + 4\n' > entradas.py

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Pide el precio a tres objetos distintos

Comando
python3 -c "from entradas import Entrada, EntradaEstudiante, EntradaVip; print(Entrada(10).precio(), EntradaEstudiante(10).precio(), EntradaVip(10, 'zumo').precio())"

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Comprueba que una entrada VIP es una entrada

Comando
python3 -c "from entradas import Entrada, EntradaVip; v = EntradaVip(10, 'zumo'); print(isinstance(v, Entrada), v.bebida)"

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Un error frecuente

Advertencia

Mucha gente cree que se hereda siempre que se quiere reutilizar código. No es así. Hereda solo si la subclase es un tipo de la superclase. Una entrada no es una cartera, aunque las dos tengan un precio. Si la relación es «tiene un», se usa otra técnica, la composición.

Polimorfismo: la misma llamada, un resultado propio

La taquilla suma entradas sin saber de qué tipo es cada una. Para cada objeto llama a precio(). Cada objeto calcula el suyo.

Esto es el polimorfismo. Si mañana el cine crea una entrada para jubilados, la taquilla no cambia ni una línea.

Escribe la taquilla que suma entradas

Comando
printf 'from entradas import Entrada, EntradaEstudiante, EntradaVip\n\n\ndef total(entradas):\n    suma = 0\n    for entrada in entradas:\n        suma = suma + entrada.precio()\n    return suma\n\n\nprint(total([Entrada(10), EntradaEstudiante(10), EntradaVip(10, "zumo")]))\n' > taquilla.py

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Ejecuta la taquilla

Comando
python3 taquilla.py

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Sobre este laboratorio y su código: Laboratorio de comandos de Linux de cada día: los treinta comandos que se escriben de memoria

¿Enseñas a una clase? Asigna este módulo a tus alumnos con guía del profesor, tareas con corrección automática y un laboratorio para cada alumno.