Asociación
La asociación es un concepto fundamental en la programación orientada a objetos (POO) que describe la relación entre dos o más clases. Se refiere a cómo las clases interactúan entre sí, y es uno de los principios que permiten modelar el comportamiento y las relaciones de los objetos en el mundo real. En Java, la asociación puede representarse de varias maneras, cada una con un significado diferente.
Una relación básica entre dos clases es donde una clase contiene un objeto de otra clase como un atributo. Por ejemplo, un Estudiante puede tener un objeto Curso asociado a él.
class Estudiante {
private String nombre;
private Curso curso; // Asociación Simple
public Estudiante(String nombre, Curso curso) {
this.nombre = nombre;
this.curso = curso;
}
public void mostrarCurso() {
System.out.println(nombre + " está inscrito en el curso: " + curso.getNombre());
}
}
class Curso {
private String nombre;
public Curso(String nombre) {
this.nombre = nombre;
}
public String getNombre() {
return nombre;
}
}
Tipos de asociación
La asociación puede ser de dos tipos: unidireccional y bidireccional.
Asociación unidireccional
En este tipo de asociación, una clase conoce a la otra, pero no al revés. Por ejemplo, un Libro puede tener un objeto de la clase Autor, pero el Autor no sabe nada sobre el Libro que escribió.
class Autor {
private String nombre;
public Autor(String nombre) {
this.nombre = nombre;
}
}
class Libro {
private String titulo;
private Autor autor;
public Libro(String titulo, Autor autor) {
this.titulo = titulo;
this.autor = autor;
}
}
Asociación bidireccional
En este tipo de asociación, ambas clases se conocen entre sí. Por ejemplo, un Coche y un Conductor pueden tener una relación bidireccional, donde cada uno sabe sobre el otro.
class Conductor {
private String nombre;
private Coche coche;
public Conductor(String nombre) {
this.nombre = nombre;
}
public void asignarCoche(Coche coche) {
this.coche = coche;
coche.setConductor(this);
}
public void conducir() {
if (coche != null) {
System.out.println(nombre + " está conduciendo un " + coche.getModelo());
}
}
}
class Coche {
private String modelo;
private Conductor conductor;
public Coche(String modelo) {
this.modelo = modelo;
}
public void setConductor(Conductor conductor) {
this.conductor = conductor;
}
public String getModelo() {
return modelo;
}
}
Multiplicidad
La asociación puede tener diferentes multiplicidades, como uno-a-uno (1:1) como las que vimos hasta ahora, uno-a-muchos (1:N), muchos-a-muchos (N:M), dependiendo de cómo las clases interactúan entre sí.
Asociación unidireccional 1:N
Vamos a crear un ejemplo que ilustre la asociación unidireccional 1:N entre las clases Departamento y Empleado. En este ejemplo, un objeto de la clase Departamento puede tener varios objetos de la clase Empleado, pero un objeto de la clase Empleado solo puede pertenecer a un Departamento.
class Empleado {
private String nombre;
public Empleado(String nombre) {
this.nombre = nombre;
}
public String getNombre() {
return nombre;
}
}
import java.util.ArrayList;
class Departamento {
private String nombre;
private ArrayList<Empleado> empleados; // Asociación de multiplicidad 1:N: Departamento tiene varios Empleados
public Departamento(String nombre) {
this.nombre = nombre;
this.empleados = new ArrayList<>(); // Inicializa la lista de empleados
}
public void addEmpleado(Empleado empleado) {
this.empleados.add(empleado); // Añade un empleado al departamento
}
public void mostrarEmpleados() {
System.out.println("Empleados en el departamento de " + nombre + ":");
for (Empleado empleado : this.empleados) {
System.out.println("- " + empleado.getNombre());
}
}
}
public class App {
public static void main(String[] args) {
// Crear empleados
Empleado empleado1 = new Empleado("Carlos");
Empleado empleado2 = new Empleado("Ana");
// Crear departamento
Departamento departamento = new Departamento("Recursos Humanos");
// Añadir empleados al departamento
departamento.addEmpleado(empleado1);
departamento.addEmpleado(empleado2);
// Mostrar empleados del departamento
departamento.mostrarEmpleados();
}
}
Asociación bidireccional 1:N
Haciendo una pequeña variación en el código podríamos convertir la asociación en asociación bidireccional 1:N.
class Empleado {
private String nombre;
private Departamento departamento; // Atributo donde almacenamos el departamento para hacerla bidireccional
public Empleado(String nombre) {
this.nombre = nombre;
}
public String getNombre() {
return nombre;
}
public void setDepartamento(Departamento departamento) {
this.departamento = departamento;
}
}
import java.util.ArrayList;
class Departamento {
private String nombre;
private ArrayList<Empleado> empleados; // Asociación de multiplicidad 1:N: Departamento tiene varios Empleados
public Departamento(String nombre) {
this.nombre = nombre;
this.empleados = new ArrayList<>(); // Inicializa la lista de empleados
}
public void addEmpleado(Empleado empleado) {
this.empleados.add(empleado); // Añade un empleado al departamento
empleado.setDepartamento(this); // Asignamos al empleado el departamento
}
public void mostrarEmpleados() {
System.out.println("Empleados en el departamento de " + nombre + ":");
for (Empleado empleado : this.empleados) {
System.out.println("- " + empleado.getNombre());
}
}
}
Asociación bidireccional N:M
Si queremos, podemos cambiar el requisito del problema para convertir la relación en una N:M. La diferencia es que en este caso, un Empleado puede ser parte de varios Departamento. En este caso también haremos la relación bidireccional.
class Empleado {
private String nombre;
private ArrayList<Departamento> departamentos; // Atributo donde almacenamos los departamentos para hacerla bidireccional
public Empleado(String nombre) {
this.nombre = nombre;
this.departamentos = new ArrayList<Departamento>();
}
public String getNombre() {
return nombre;
}
public void addDepartamento(Departamento departamento) {
this.departamentos.add(departamento);
}
}
import java.util.ArrayList;
class Departamento {
private String nombre;
private ArrayList<Empleado> empleados;
public Departamento(String nombre) {
this.nombre = nombre;
this.empleados = new ArrayList<>();
}
public void addEmpleado(Empleado empleado) {
this.empleados.add(empleado); // Añade un empleado al departamento
empleado.addDepartamento(this); // Añadimos el departamento al empleado
}
public void mostrarEmpleados() {
System.out.println("Empleados en el departamento de " + nombre + ":");
for (Empleado empleado : this.empleados) {
System.out.println("- " + empleado.getNombre());
}
}
}