Herencia y Composición en Patrones de Diseño
Clase 12 de 14 • Curso de Introducción a los Patrones de Diseño de Software
Resumen
¿Qué es la herencia en la programación orientada a objetos?
La herencia es uno de los conceptos clave en la programación orientada a objetos que permite a las clases compartir atributos y métodos. Cuando hablamos de herencia, nos referimos a la relación estrecha que existe entre una subclase y una superclase, donde la subclase hereda comportamientos y funcionalidades de la superclase para evitar la redundancia de código.
Aspectos importantes de la herencia
-
Acoplamiento estrecho: La subclase y la superclase están estrechamente vinculadas. Cambios en la superclase pueden afectar inmediatamente a las subclases derivadas.
-
Limitaciones en la interfaz: Una subclase no tiene la capacidad de reducir la interfaz pública de su superclase. Esto significa que no puede eliminar o modificar métodos existentes, aunque sí puede extender su funcionalidad añadiendo nuevos métodos.
-
Taxonomías complejas: La herencia puede llevar a la creación de jerarquías extensas y complejas. Este fenómeno, conocido como taxonomía, puede dificultar la mantenibilidad y comprensión del código si no se gestiona adecuadamente.
Ejemplo de herencia
class SuperClase:
def metodo_original(self):
return "Método de la superclase"
class SubClase(SuperClase):
def nuevo_metodo(self):
return "Método extendido de la subclase"
En este ejemplo, SubClase
hereda de SuperClase
y extiende su comportamiento añadiendo nuevo_metodo
.
¿Por qué elegir la composición sobre la herencia?
Existe un conocido principio de diseño que recomienda optar por la composición antes que por la herencia. ¿Por qué? Este enfoque puede resultar en soluciones más flexibles y menos acopladas al evitar jerarquías de herencia innecesariamente complejas.
¿Cómo definimos la composición?
La composición se refiere a la relación entre dos clases donde una clase contiene objetos de otra clase dentro de sus propiedades. Es como decir que una clase está "compuesta" por diferentes componentes más pequeños.
Ejemplo de composición
Consideremos el ejemplo de un carro:
class Engine:
def start(self):
return "El motor ha arrancado"
class Car:
def __init__(self, engine):
self.engine = engine
def move(self):
return self.engine.start()
En este caso, Car
no hereda de Engine
, sino que contiene un objeto de Engine
como una de sus propiedades. Esto permite que Car
utilice el método start
del motor sin necesidad de heredar de la clase Engine
.
Ventajas de la composición
- Flexibilidad: Permite modificar o añadir funcionalidades sin alterar las clases existentes.
- Desacoplamiento: Reduce el acoplamiento entre clases, lo que mejora la mantenibilidad del código.
Reflexiones finales: Elegir herencia o composición
No siempre es blanco y negro. La elección entre herencia y composición depende de la solución específica que se quiera implementar. Es esencial considerar el contexto del problema al decidir cuál usar. Aunque la composición ofrece varias ventajas, la herencia sigue siendo una herramienta valiosa cuando se utiliza con criterio y conocimiento.
La clave está en entender ambos conceptos, sus ventajas y también sus limitaciones. Así, podrás aplicar un enfoque versátil y adaptado a las necesidades de tu proyecto. ¡Sigue explorando y aprendiendo para desarrollar un código más robusto y eficiente!