UML: Relaciones entre Clases

Las relaciones entre clases también están contempladas en UML, dado que, durante el diseño, es muy útil especificar claramente cualquier relación, que deberá ser traducida luego al código.

Composición
En UML, la composición se representa mediante una línea que une las dos clases, pero colocando un pequeño rombo del lado de la clase que se compone a partir de la otra. Opcionalmente, se puede indicar el nombre de la propiedad que representa la composición, pero no es muy habitual hacerlo, sobre todo en las etapas iniciales del análisis.

En la figura, vemos que una Escuela se compone de Aulas. Observemos los pequeños números debajo de la línea. Estos números indican la multiplicidad, es decir, cuántos elementos pueden existir de cada lado. El asterisco (*) indica muchos, sin especificar cuántos. Según esto, el diagrama deja bien claro que una escuela se compone de muchas aulas. Del mismo modo, si leemos la multiplicidad en sentido inverso, podemos entender que un aula está sólo en una escuela.

UML permite especificar la relación de composición, indicando además
cuántos elementos de una clase componen a la otra.

Además, sobre la línea que indica la relación, se puede colocar un texto aclaratorio sobre el tipo de composición. En el ejemplo, hemos especificado Posee como nombre de la relación. Si bien es opcional, el nombre de la relación ayuda mucho a la claridad del diagrama y a su posterior implementación en un lenguaje de programación.

Asociación simple
Anteriormente vimos que, si el tipo de dato de una propiedad es una clase, podemos escribirlo directamente o bien utilizar una relación de asociación. Hay una tercera opción que es usar ambos al mismo tiempo, pero no la veremos ahora.
La relación de asociación se representa de manera similar a la composición, pero sin utilizar el rombo; simplemente se coloca una línea entre las dos clases asociadas y una flecha que indica el sentido de la asociación. Al igual que en la composición, puede agregarse el nombre de la relación para aumentar la riqueza del modelo.

La relación de asociación es similar a la composición,
pero se utiliza una flecha para indicar el sentido de la relación.

PROGRAMACION Y DISEÑO Los conceptos introducidos por la POO como forma de trabajo, no sólo se aplican a la programación propiamente dicha, sino que también se puede hacer análisis orientado a objetos, y diseño orientado a objetos. UML está pensado para la creación de diagramas usando este paradigma.

Herencia
La relación de herencia también tiene su forma particular dentro del lenguaje UML. La representación de la herencia consiste en una flecha con la punta sin rellenar (en blanco). Lo más común es colocar las clases derivadas debajo de la clase base, de manera que la flecha que representa la herencia tenga sentido de abajo hacia arriba, generando un diagrama tipo árbol. Si la clase base es abstracta, se debe colocar el nombre con letra itálica (por ejemplo, Figura). Aunque parezca una obviedad (dada la definición de herencia) tengamos en cuenta que, en el diagrama de las clases derivadas, no es necesario volver a indicar las propiedades y los métodos heredados.

La herencia se representa mediante flechas sin relleno, apuntando hacia la clase base.

En el caso de las interfaces, UML prevé una forma de representarlas, como así también una notación especial para indicar la implementación de una interfaz por parte de una clase. Para indicar que se trata de una interfaz y no de una clase, en el diagrama de clases se debe colocar el indicador interfaz sobre el nombre, en la primera división del rectángulo que representa en este caso la interfaz. Además, si bien desde el punto de vista del polimorfismo la implementación de interfaces resulta similar a la herencia, no es lo mismo, por lo que UML hace la distinción correspondiente. Para especificar que una clase implementa una interfaz, se debe colocar una flecha de punta hueca apuntando hacia la interfaz, pero con línea punteada. En la Figura se aprecia una interfaz (IComunicador) y una clase, la que implementa (ComunicadorPorModem). Notemos que, a diferencia del diagrama de herencia, aquí sí debemos especificar en la clase todos los métodos y propiedades de la interfaz, ya que al aceptar el contrato que la interfaz nos impone, debemos implementarlo completamente (caso contrario ni el modelo ni el código serán válidos).

Al modelar la implementación de una interfaz, debemos volver a indicar
todas las propiedades y métodos en la clase que la implementa.