- ¿Qué es la herencia?
- Usar la herencia
- Herencia múltiple y cadenas de clases
- Cómo saber de qué clase es un objeto
- Polimorfismo y mejores prácticas
A veces, al programar, queremos crear algo nuevo que se parezca a algo que ya hicimos, pero con algunos cambios. En lugar de empezar desde cero, podemos aprovechar lo que ya existe y adaptarlo. Eso es lo que llamamos herencia, una herramienta muy útil en la programación orientada a objetos.
¿Qué es la herencia?
La herencia es una forma de crear una clase nueva (llamada subclase o clase hija) a partir de otra clase existente (llamada superclase o clase padre).
La subclase hereda todo el comportamiento y las propiedades de la superclase, como los métodos y atributos.
Vamos a ver un ejemplo simple: un modelo de elementos HTML.
Clase base
Primero creamos una clase que defina lo básico que tienen todos los elementos HTML:
class HTMLElement:
def __init__(self, attributes=None):
self.attributes = attributes if attributes else {}
self.body = None
def set_attribute(self, key, value):
self.attributes[key] = value
def get_attribute(self, key):
return self.attributes.get(key)
def set_text_content(self, body):
self.body = body
def get_text_content(self):
return self.body
def stringify_attributes(self):
# Convierte los atributos en algo como: key="value" key2="value2"
return ' ' + ' '.join(
f'{key}="{value}"' for key, value in self.attributes.items()
) if self.attributes else ''
Esta clase HTMLElement es una especie de plantilla para cualquier etiqueta HTML. Sirve para guardar atributos (como href o class) y contenido (el texto que va dentro del elemento).
Subclase que hereda
Ahora queremos representar específicamente una etiqueta <a> (enlace). En lugar de volver a escribir todo, hacemos una subclase que herede:
class HTMLAnchorElement(HTMLElement):
def __str__(self):
attr_line = self.stringify_attributes()
body = self.get_text_content()
return f'<a{attr_line}>{body}</a>'
Aquí creamos la clase HTMLAnchorElement que hereda de HTMLElement. Solo escribimos lo que cambia: cómo se ve el HTML para esta etiqueta cuando lo imprimimos.
ClaseHija(ClasePadre) para definir herencia.
Usar la herencia
Veamos cómo se comportan estos objetos en acción:
anchor = HTMLAnchorElement({'href': 'https://codica.la'})
anchor.set_text_content('Códica')
print(f"Anchor: { anchor }")
Imprime:
Anchor: <a href="https://codica.la"> Códica </a>
Esto funciona porque:
- Aunque
HTMLAnchorElementno tiene métodoset_text_content, sí lo hereda deHTMLElement. - Al imprimir
anchor, Python llama al método especial__str__(), que definimos para mostrar el HTML como una cadena.
Herencia múltiple y cadenas de clases
Python es flexible: permite heredar de una sola clase (lo más común) o de varias al tiempo.
class D: pass
class C(D): pass
class B(C, D): pass # Herencia múltiple
class A(B): pass
Este ejemplo muestra cómo una clase puede heredar de varias otras. A esto se le llama cadena de herencias.
Cómo saber de qué clase es un objeto
En programas más grandes, a veces necesitamos saber si un objeto pertenece a cierta clase.
Para eso usamos dos funciones:
La función isinstance()
Sirve para saber si un objeto es de una clase, o de alguna subclase de ella.
print(isinstance(anchor, HTMLElement)) # True, porque HTMLAnchorElement hereda de HTMLElement
La función type()
Verifica si un objeto es exactamente de cierto tipo (sin tener en cuenta herencia).
print(type(anchor) == HTMLAnchorElement) # True
print(type(anchor) == HTMLElement) # False
En general, preferimos isinstance() porque funciona mejor en sistemas con herencia y favorece el uso del principio de polimorfismo.
Polimorfismo y mejores prácticas
El polimorfismo es cuando usamos objetos de diferentes clases a través de una misma interfaz. En lugar de preguntar "¿qué clase es esto?", simplemente usamos los métodos que esperamos, y si ese objeto los tiene, ¡funciona! Esto hace el código más limpio y más flexible a cambios.
Por eso, en muchos casos es mejor confiar en que los objetos tienen los métodos que necesitamos, en lugar de preguntar por su tipo.
Resumen
- Herencia permite reutilizar código al crear clases basadas en otras.
- Una subclase hereda atributos y métodos de su clase padre.
- Se puede sobreescribir lo que necesitemos (como el método
__str__()). - Python permite herencia múltiple.
- Usamos
isinstance()para verificar tipos considerando herencia. - Usamos
type()para verificar el tipo exacto de un objeto. - Es recomendable usar polimorfismo para evitar acoplar el código a clases específicas.
Materiales adicionales
Para acceder completo a curso necesitas un plan básico
El plan básico te dará acceso completo a todos los cursos, ejercicios y lecciones de Códica, proyectos y acceso de por vida a la teoría de las lecciones completadas. La suscripción se puede cancelar en cualquier momento.