Composición de objetos
En la Programación Orientada a Objetos (POO), uno de los mecanismos fundamentales para modelar relaciones entre entidades del mundo real es la composición, también conocida como relación “tiene un” (has-a). Esta técnica permite construir clases complejas a partir de otras clases, fomentando el diseño modular y la reutilización de código.
La composición implica que una clase contiene como atributos a objetos de otras clases. Esta relación se describe informalmente como:
- “Un coche tiene un motor.”
- “Una persona tiene una dirección.”
- “Un pedido tiene una fecha.”
Las ventajas de la composición son:
- Permite construir clases complejas a partir de otras más simples.
- Favorece la reutilización y el diseño modular.
- Refleja relaciones del mundo real de forma natural.
- Mejora la legibilidad y mantenibilidad del código.
En términos de C++, se dice que una clase compone otras clases cuando declara objetos de esas clases como atributos.
Clases que contienen objetos de otras clases
Para lograr la composición en C++, simplemente se declara como atributo un objeto de otra clase dentro de la definición de una clase. Veamos un ejemplo:
#include <iostream>
#include <string>
class Direccion {
private:
std::string calle;
std::string ciudad;
public:
// Constructor por defecto usando lista de inicialización
Direccion() : calle{""}, ciudad{""} {}
// Constructor con parámetros usando lista de inicialización
Direccion(const std::string& c, const std::string& ciu)
: calle{c}, ciudad{ciu} {}
void mostrar() const {
std::cout << "Calle: " << calle << ", Ciudad: " << ciudad << std::endl;
}
};
class Persona {
private:
std::string nombre;
Direccion direccion; // Composición: una Persona tiene una Direccion
public:
// Constructor usando lista de inicialización para todos los miembros
Persona(const std::string& n, const Direccion& d)
: nombre{n}, direccion{d} {}
void mostrar() const {
std::cout << "Nombre: " << nombre << std::endl;
direccion.mostrar();
}
};
int main() {
Direccion dir("Calle Mayor 123", "Madrid");
Persona p("Juan", dir);
p.mostrar();
return 0;
}
- Cuando se crea un objeto de tipo
Persona, automáticamente se construye también el objetoDireccioncontenido en su interior. - El destructor de
Direccionse invoca automáticamente cuando se destruye el objetoPersona. - La composición garantiza que los objetos contenidos existen mientras exista el objeto que los compone.