Herencia en Python

¿En qué consiste la herencia en Python?

La herencia es uno de los conceptos fundamentales de la programación orientada a objetos, y Python lo soporta de manera nativa. La herencia permite definir una clase que hereda atributos y métodos de una clase existente, permitiendo la reutilización de código y la organización jerárquica de las clases.

La clase que hereda se conoce como “subclase” o “clase hija”, y la clase de la que hereda se conoce como “superclase” o “clase padre”.

La sintaxis para definir una subclase en Python es la siguiente:


class SubClase(SuperClase):
    # Definición de la subclase

Lenguaje del código: Python (python)

La subclase heredará todos los atributos y métodos de la superclase, y también puede definir sus propios atributos y métodos.

Veamos un ejemplo concreto para ilustrar cómo funciona la herencia en Python:


class Animal:
    def __init__(self, nombre):
        self.nombre = nombre

    def hacer_sonido(self):
        print("El animal hace un sonido.")

class Perro(Animal):
    def hacer_sonido(self):
        print("El perro ladra.")

class Gato(Animal):
    def hacer_sonido(self):
        print("El gato maúlla.")

Lenguaje del código: Python (python)

En este ejemplo, tenemos una clase Animal que define un atributo nombre y un método hacer_sonido. También tenemos dos subclases, Perro y Gato, que heredan de Animal y sobrescriben el método hacer_sonido para implementar sonidos específicos de cada animal.

Podemos crear instancias de estas clases y llamar a sus métodos de la siguiente manera:


animal = Animal("Fido")
animal.hacer_sonido()  # Imprime "El animal hace un sonido."

perro = Perro("Pluto")
perro.hacer_sonido()  # Imprime "El perro ladra."

gato = Gato("Garfield")
gato.hacer_sonido()  # Imprime "El gato maúlla."

Lenguaje del código: Python (python)

En este ejemplo, vemos que Perro y Gato heredan el atributo nombre y el método hacer_sonido de Animal, pero sobrescriben el método hacer_sonido para proporcionar su propio comportamiento.

Extendiendo y modificando métodos

Además de heredar atributos y métodos de una superclase, las subclases también pueden extender o modificar los métodos de la superclase. Esto se logra mediante la sobrescritura de los métodos de la superclase en la subclase.

En Python, podemos sobrescribir un método simplemente definiéndolo en la subclase con el mismo nombre que el método de la superclase. La nueva implementación reemplazará la implementación de la superclase. Aquí hay un ejemplo que muestra cómo sobrescribir un método en una subclase:


class Animal:
    def __init__(self, nombre):
        self.nombre = nombre

    def hacer_sonido(self):
        print("El animal hace un sonido.")

class Perro(Animal):
    def hacer_sonido(self):
        print("El perro ladra.")

    def correr(self):
        print("El perro corre.")

class Gato(Animal):
    def hacer_sonido(self):
        print("El gato maúlla.")

    def saltar(self):
        print("El gato salta.")

perro = Perro("Pluto")
perro.hacer_sonido()  # Imprime "El perro ladra."
perro.correr()  # Imprime "El perro corre."

gato = Gato("Garfield")
gato.hacer_sonido()  # Imprime "El gato maúlla."
gato.saltar()  # Imprime "El gato salta."

Lenguaje del código: Python (python)

En este ejemplo, la subclase Perro sobrescribe el método hacer_sonido de la superclase Animal para proporcionar una implementación que imprime “El perro ladra”.

También agrega un nuevo método correr que no existe en la superclase. La subclase Gato hace lo mismo al sobrescribir el método hacer_sonido y agregar un nuevo método saltar.

Uso de la función super()

La función super() es una función incorporada en Python que se utiliza para llamar a un método de una superclase desde una subclase.

En otras palabras, super() nos permite acceder a los métodos y atributos de la superclase en la subclase.

La sintaxis de super() es la siguiente:


super([tipo[, objeto]])

Lenguaje del código: Python (python)

El primer argumento, tipo, es opcional y se utiliza para especificar la clase de la que se debe llamar al método. El segundo argumento, objeto, también es opcional y se utiliza para especificar la instancia de la subclase que se está usando.

Si no se proporciona ninguno de los argumentos, super() usará automáticamente la clase y la instancia actual.

Aquí hay un ejemplo que muestra cómo utilizar super() para llamar a un método de la superclase en una subclase:


class Animal:
    def __init__(self, nombre):
        self.nombre = nombre

    def hacer_sonido(self):
        print("El animal hace un sonido.")

class Perro(Animal):
    def hacer_sonido(self):
        super().hacer_sonido()
        print("El perro ladra.")

perro = Perro("Pluto")
perro.hacer_sonido()  # Imprime "El animal hace un sonido." seguido de "El perro ladra."

Lenguaje del código: Python (python)

En este ejemplo, la subclase Perro sobrescribe el método hacer_sonido de la superclase Animal. Sin embargo, antes de imprimir “El perro ladra”, la subclase llama al método hacer_sonido de la superclase usando super(). Esto permite que la subclase extienda la implementación de la superclase sin tener que volver a escribirla por completo.

También es importante tener en cuenta que super() se utiliza a menudo en conjunto con el método __init__ para inicializar las variables de la superclase. Aquí hay un ejemplo que ilustra cómo usar super() en el método __init__ de una subclase:


class Animal:
    def __init__(self, nombre):
        self.nombre = nombre

class Perro(Animal):
    def __init__(self, nombre, raza):
        super().__init__(nombre)
        self.raza = raza

perro = Perro("Pluto", "Labrador")
print(perro.nombre)  # Imprime "Pluto"
print(perro.raza)  # Imprime "Labrador"

Lenguaje del código: Python (python)

En este ejemplo, la subclase Perro tiene un método __init__ que toma dos argumentos, nombre y raza. En el método __init__, la subclase llama al método __init__ de la superclase usando super().

Esto inicializa la variable nombre de la superclase. La subclase también inicializa su propia variable raza. Al crear una instancia de la subclase Perro, podemos ver que las variables nombre y raza se han inicializado correctamente.

Herencia múltiple

La herencia múltiple es una característica de la programación orientada a objetos que permite que una subclase herede de múltiples superclases. En Python, la herencia múltiple se implementa mediante la definición de una subclase que hereda de varias superclases.

La sintaxis para definir una subclase con herencia múltiple es la siguiente:


class SubClase(SuperClase1, SuperClase2, ..., SuperClaseN):
    # Definición de la subclase

Lenguaje del código: Python (python)

En este ejemplo, la subclase SubClase hereda de las superclases SuperClase1, SuperClase2, …, SuperClaseN. La subclase tendrá acceso a los atributos y métodos de todas las superclases.

Aquí hay un ejemplo concreto que muestra cómo funciona la herencia múltiple en Python:


class Vehiculo:
    def __init__(self, marca, modelo):
        self.marca = marca
        self.modelo = modelo

class Electrico:
    def __init__(self, bateria):
        self.bateria = bateria

    def cargar_bateria(self):
        print("Cargando la batería...")

class CocheElectrico(Vehiculo, Electrico):
    def __init__(self, marca, modelo, bateria):
        Vehiculo.__init__(self, marca, modelo)
        Electrico.__init__(self, bateria)

coche = CocheElectrico("Tesla", "Model S", "100 kWh")
print(coche.marca)  # Imprime "Tesla"
print(coche.modelo)  # Imprime "Model S"
print(coche.bateria)  # Imprime "100 kWh"
coche.cargar_bateria()  # Imprime "Cargando la batería...

Lenguaje del código: Python (python)

En este ejemplo, tenemos una clase Vehiculo que define un atributo marca y un atributo modelo, y una clase Electrico que define un atributo bateria y un método cargar_bateria.

Luego tenemos una subclase CocheElectrico que hereda de ambas superclases y define su propio constructor que inicializa los atributos de ambas superclases.

Al crear una instancia de la subclase CocheElectrico, podemos ver que tiene acceso a los atributos y métodos de ambas superclases.

IMPORTANTE: Es importante tener en cuenta que la herencia múltiple puede llevar a problemas de ambigüedad si varias superclases tienen el mismo nombre de atributo o método. En estos casos, se debe especificar explícitamente desde qué superclase se está llamando el atributo o método.