0

Introducción a los
Diagramas de Clases UML

Aprende a representar visualmente la estructura de un sistema orientado a objetos mediante el lenguaje estándar de modelado UML.

📐 UML 2.x 🧩 Programación OO 🔗 Relaciones 📦 Clases
📐

¿Qué es UML?

Unified Modeling Language — Lenguaje estándar visual para modelar sistemas de software. Los diagramas de clases son el más usado en POO.

🎯

¿Para qué sirve?

Permite diseñar antes de codificar: muestra clases, atributos, métodos y cómo se relacionan entre sí en el sistema.

🗺️

Ruta de aprendizaje

Comenzaremos con la anatomía de una clase, luego multiplicidad, y escalaremos por cada tipo de relación hasta los ejemplos completos.

📖 ¿Qué aprenderás en este módulo?
Orden pedagógico: de lo básico a lo avanzado
1️⃣ Fundamentos

Estructura de una clase · Notación UML · Visibilidad · Multiplicidad · Dependencia

2️⃣ Relaciones de Asociación

Simple · Agregación · Composición · Reflexiva — con sus notaciones y diferencias clave

3️⃣ Herencia y Realizaciones

Generalización · Herencia múltiple · Realización de interfaces — el principio "es un"

4️⃣ Avanzado

Estereotipos «call» «create» «use» y más · Ejemplos completos de sistemas reales · Quiz

🔑 Conceptos previos necesarios
🧱
Clases y Objetos
Plantilla (clase) vs instancia (objeto)
🔒
Encapsulamiento
public, private, protected
🧬
Herencia
Concepto padre–hijo en POO
🎭
Polimorfismo
Mismo nombre, comportamiento distinto
1

Anatomía de una
Clase en UML

Una clase en UML se representa con un rectángulo dividido en tres secciones: nombre, atributos y métodos.

📦 Clase🔒 Visibilidad📝 Notación

Estructura de una clase UML

Una clase UML tiene tres compartimentos:

  • Nombre: Nombre de la clase (PascalCase), puede incluir estereotipo.
  • Atributos: Variables de la clase con visibilidad y tipo.
  • Métodos: Operaciones de la clase con parámetros y tipo de retorno.
Visibilidad:
+ public · - private · # protected · ~ package
Ejemplo: clase Persona
Persona
-nombre: String
-edad: int
-email: String
+getNombre(): String
+setNombre(n: String): void
+saludar(): void
📋 Tabla de Visibilidad
SímboloNombreAcceso desde…Ejemplo
+publicCualquier clase+ getNombre(): String
-privateSolo la propia clase- nombre: String
#protectedClase y sus subclases# id: int
~packageMismo paquete~ config: Map
🏷️ Tipos de clasificadores UML
«class»

Clase Concreta

Puede instanciarse directamente. Tiene implementación completa de todos sus métodos.

«abstract»

Clase Abstracta

No puede instanciarse directamente. Tiene al menos un método abstracto (sin implementar). Nombre en cursiva.

«interface»

Interfaz

Solo declara métodos sin implementación. Las clases la realizan mediante la relación de Realización.

2

Indicadores de
Multiplicidad

La multiplicidad define cuántas instancias de una clase pueden relacionarse con instancias de otra. Se coloca en los extremos de las líneas de relación.

🔢 Cardinalidad↔ Extremos
1
Exactamente uno
Obligatoriamente una y solo una instancia.
0..1
Cero o uno
Opcional: ninguna o una instancia (como un campo nullable).
*
Muchos
Cero o más instancias (equivalente a 0..*).
0..*
Cero o más
Ninguna o varias instancias (más explícito que *).
1..*
Uno o más
Al menos una instancia obligatoria, puede ser más.
n
Exactamente n
Número fijo específico (ej: 4 ruedas en un auto).
m..n
Rango fijo
Entre m y n instancias (ej: 2..5 jugadores).
2..4
Ejemplo concreto
Mínimo 2, máximo 4 instancias relacionadas.
📊 Ejemplos de multiplicidad en relaciones
EscenarioMultiplicidadLectura
Un Autor puede publicar varios Libros10..*Un autor tiene cero o más libros
Un Pedido tiene al menos un Producto11..*Un pedido tiene uno o más productos
Un Empleado puede tener un Jefe (o no)10..1Un empleado tiene cero o un jefe
Un Equipo de fútbol tiene 11 jugadores111Un equipo tiene exactamente 11 jugadores
Torneo con 2 a 8 equipos12..8Un torneo incluye entre 2 y 8 equipos
🖼️ Dónde se coloca la multiplicidad
ClaseA ClaseB 1 0..* extremo de ClaseA extremo de ClaseB relación
Regla de lectura: Lee la multiplicidad desde el extremo OPUESTO. La multiplicidad junto a ClaseB dice cuántas instancias de B puede tener una instancia de A.
3

Dependencia

La relación más débil entre clases. Una clase "cliente" usa temporalmente a otra "proveedor", sin mantenerla como atributo permanente.

⚡ Débil- - → Línea punteadaTemporal

¿Qué es la Dependencia?

Una dependencia indica que un cambio en el proveedor puede afectar al cliente, pero la relación es temporal y no implica que el cliente "tenga" al proveedor como atributo.

Se usa cuando una clase:

  • Recibe un objeto como parámetro de un método
  • Crea un objeto localmente dentro de un método
  • Llama un método estático de otra clase
  • Devuelve un tipo de la clase dependida
Notación: Línea punteada con flecha abierta apuntando al proveedor. Opcionalmente lleva un estereotipo «use», «call», etc.
Diagrama de dependencia
Pedido + calcularTotal( imp: Impuesto ): double Impuesto + calcular(base: double): double «use»
Pedido usa Impuesto como parámetro
💻 Ejemplo en código
class Pedido {
  public double calcularTotal(Impuesto imp) {
    // imp es un parámetro temporal → dependencia
    double base = obtenerSubtotal();
    return base + imp.calcular(base);
  }
}

class Impuesto {
  public double calcular(double base) {
    return base * 0.18; // IGV 18%
  }
}
Clave para identificarla: Si el objeto de otra clase solo aparece como parámetro o variable local (no como atributo de la clase), es una Dependencia, no una Asociación.
4

Asociación Simple

Relación permanente entre dos clases donde una "conoce" y mantiene una referencia a la otra como atributo. Es la relación más común en diagramas OO.

🔗 Permanente— Línea sólidaBidireccional / Unidireccional

Características

Una Asociación significa que un objeto de la clase A mantiene una referencia permanente a uno o más objetos de la clase B (o viceversa).

  • Unidireccional: A conoce a B, pero B no conoce a A. Se agrega una flecha.
  • Bidireccional: Ambas clases se conocen mutuamente. Sin flecha (o con dos flechas).
  • Se puede nombrar la relación y agregar multiplicidad en ambos extremos.
En código: La asociación se implementa como un atributo en la clase. Si Persona tiene un atributo de tipo Dirección, hay una asociación.
Bidireccional Estudiante Curso * * inscrito en / tiene Unidireccional (con flecha) Persona Dirección 1 1..* Persona conoce a Dirección Con nombre de asociación Empleado Empresa trabaja en ▶ 1..* 1
💻 Código equivalente
class Persona {
  // Asociación: Persona tiene una referencia a Dirección
  private List<Dirección> direcciones; // 1..*
}

class Dirección {
  private String calle;
  private String ciudad;
}
5

Agregación

Relación "todo-parte" donde las partes pueden existir independientemente del todo. El diamante vacío aparece en el extremo del "todo".

◇ Diamante vacíoTodo–ParteIndependencia

¿Qué es la Agregación?

Es una asociación especial que modela una relación "tiene un" donde el todo agrupa partes, pero las partes pueden existir de forma independiente al todo.

Si el todo se destruye, las partes siguen existiendo y pueden pertenecer a otro todo.

Características clave:

  • Las partes tienen ciclo de vida independiente.
  • Una parte puede pertenecer a múltiples todos.
  • Se dibuja con un diamante vacío (◇) en el extremo del todo.
Ejemplo clásico: Universidad ◇── Profesor. Si la universidad cierra, el profesor sigue existiendo (puede ir a otra universidad).
Universidad - nombre: String + agregarProf(): void Profesor - nombre: String - especialidad: String 1 1..* TODO PARTE ◇ indica que es el "todo"
💻 Código equivalente
class Universidad {
  // Agregación: Universidad tiene profesores, pero ellos existen sin ella
  private List<Profesor> profesores;

  public Universidad(List<Profesor> profs) {
    // Profesores creados fuera → vienen de afuera (no son creados aquí)
    this.profesores = profs;
  }
}
6

Composición

Relación "todo-parte" fuerte: las partes NO pueden existir sin el todo. Ciclo de vida compartido. Diamante relleno en el extremo del "todo".

◆ Diamante rellenoCiclo de vida compartidoExclusivo

¿Qué es la Composición?

Es la forma más fuerte de agregación. El todo posee y controla la vida de las partes: si el todo se destruye, las partes también desaparecen.

Características clave:

  • Las partes tienen ciclo de vida dependiente del todo.
  • Una parte solo puede pertenecer a un todo a la vez.
  • El todo crea y destruye a sus partes.
  • Se dibuja con un diamante relleno (◆) en el extremo del todo.
Ejemplo clásico: Casa ◆── Habitación. Si la casa se demuele, las habitaciones ya no existen. Una habitación no puede existir sin su casa.
Casa - dirección: String - numHabitaciones: int Habitacion - numero: int - area: double - tipo: String 1 1..* TODO (posee) PARTE (dependiente) ◆ indica relación fuerte
⚖️ Agregación vs Composición — Comparación
Característica◇ Agregación◆ Composición
Ciclo de vidaIndependienteDependiente (compartido)
¿La parte sobrevive sin el todo?✅ Sí❌ No
¿Una parte puede tener varios todos?✅ Sí❌ No (solo uno)
¿Quién crea las partes?Alguien externoEl propio todo
Símbolo UMLDiamante vacío ◇Diamante relleno ◆
EjemploUniversidad — ProfesorCasa — Habitación
7

Asociación Reflexiva

Una clase se relaciona con instancias de SU MISMO tipo. La línea de asociación conecta la clase consigo misma, formando un bucle.

🔄 Auto-referenciaMismo tipoRecursiva

¿Qué es la Asociación Reflexiva?

Ocurre cuando objetos de la misma clase se relacionan entre sí. La línea de asociación parte y termina en la misma clase.

Es muy común en estructuras jerárquicas o cuando objetos del mismo tipo se supervisan, contienen o referencian entre sí.

Casos de uso frecuentes:

  • Jerarquía organizacional: Empleado supervisa a Empleado
  • Estructuras de árbol: Nodo contiene Nodos hijos
  • Categorías: Categoría tiene subcategorías
  • Redes: Persona conoce a otras Personas
Empleado - id: int - nombre: String - jefe: Empleado supervisa 0..* 0..1
💻 Código equivalente
class Empleado {
  private int id;
  private String nombre;
  // Asociación reflexiva: un Empleado puede supervisar otros Empleados
  private Empleado jefe; // 0..1 jefe
  private List<Empleado> subordinados; // 0..* subordinados
}
Truco visual: En el diagrama, la línea de la asociación reflexiva sale de un lado de la clase y vuelve al mismo extremo (o a otro lado de la misma caja). Es inconfundible.
8

Herencia y Generalización

La relación "ES UN TIPO DE". Una subclase hereda atributos y métodos de su superclase, pudiendo extenderlos o sobreescribirlos. Triangulo vacío hacia el padre.

▷ Triángulo vacíoES-UN (is-a)extends

Generalización en UML

La generalización representa la relación "es un tipo de". La subclase hereda todos los atributos y métodos de la superclase, y puede agregar los suyos propios.

  • La subclase (hijo) apunta hacia la superclase (padre).
  • Se dibuja con una flecha de triángulo vacío (▷) en la punta del padre.
  • La subclase puede sobreescribir métodos (polimorfismo).
  • Los métodos abstractos aparecen en cursiva.
Prueba del "es un": Si puedes decir "un Perro ES UN Animal", entonces Perro hereda de Animal. Si no, no debe ser herencia.
Animal - nombre: String - peso: double + sonido(): String + comer(): void Perro - raza: String + sonido(): String + buscarPalo(): void Gato - indoor: boolean + sonido(): String + ronronear(): void ▷ flecha apunta al padre
🔀 Herencia Múltiple

En algunos lenguajes (C++, Python) y en UML, una clase puede heredar de dos o más superclases. En Java/C# no se permite directamente (se usa interfaces).

Volador + volar(): void Nadador + nadar(): void Pato + graznar(): void + volar() + nadar()

Pato hereda de Volador y Nadador (herencia múltiple)

9

Realización

Una clase concreta implementa los métodos declarados por una interfaz. Línea punteada con triángulo vacío hacia la interfaz. Principio: "PUEDE COMPORTARSE COMO".

⇢ Línea punteada + triángulo«interface»implements

¿Qué es la Realización?

Conecta una clase concreta con una interfaz. La clase se compromete a implementar todos los métodos declarados en la interfaz.

  • La interfaz declara qué debe hacerse (contrato).
  • La clase implementa cómo se hace.
  • Se dibuja con línea punteada y triángulo vacío apuntando a la interfaz.
  • Una clase puede implementar múltiples interfaces.
Diferencia con Herencia:
Herencia → línea continua + triángulo vacío → la subclase extiende a la superclase.
Realización → línea punteada + triángulo vacío → la clase implementa la interfaz.
«interface» Serializable + serializar(): byte[] + deserializar(): void Documento - contenido: String + serializar(): byte[] + deserializar(): void Imagen - pixeles: int[][] + serializar(): byte[] + deserializar(): void
💻 Código equivalente (Java)
interface Serializable {
  byte[] serializar();
  void deserializar(byte[] datos);
}

class Documento implements Serializable {
  public byte[] serializar() { /* implementación */ }
  public void deserializar(byte[] d) { /* implementación */ }
}
10

Estereotipos de
Dependencia UML

Los estereotipos refinan el tipo de dependencia entre clases, indicando exactamente cómo una clase usa a otra. Se escriben entre «guillemets».

«call»«create»«use»«derive»«instantiate»
📚 Tabla de Estereotipos
EstereotipoSignificadoEjemplo de uso
«call»Una operación de A invoca una operación de BSistema «call» Logger.registrar()
«create»A crea instancias de B (A es fábrica de B)Fábrica «create» Producto
«derive»El elemento destino se puede calcular desde AEdadActual «derive» FechaNacimiento
«instantiate»A crea objetos de la clase B (más específico que «create»)Builder «instantiate» Objeto
«permit»B otorga permiso especial de acceso a A (como friend en C++)Prueba «permit» ClasePrivada
«refine»A es una especificación más detallada de B (otro nivel de abstracción)DiseñoDetallado «refine» DiseñoAltoNivel
«use»A requiere B para su implementación correcta (dependencia genérica)Controlador «use» ServicioPago
🎴 Estereotipos en detalle
«call»
Llamada de operación
Una operación de la clase cliente llama a una operación de la clase proveedor.
Controlador «call» Logger
«create»
Creación de instancias
La clase cliente crea instancias de la clase proveedor. Patrón Factory.
FábricaAuto «create» Auto
«derive»
Derivación
El elemento destino puede derivarse o calcularse a partir del origen.
Edad «derive» FechaNac
«instantiate»
Instanciación
La clase cliente crea objetos de la clase proveedor (más preciso que «create»).
Builder «instantiate» Casa
«permit»
Permiso de acceso
El proveedor concede acceso especial a miembros privados al cliente.
Test «permit» ClaseInternal
«refine»
Refinamiento
El cliente es una especificación más detallada del proveedor en otro nivel.
DisñoDetalle «refine» DisnoPlan
«use»
Uso genérico
El cliente requiere del proveedor para funcionar correctamente.
Servicio «use» Repositorio
🖼️ Ejemplo visual con estereotipos
App + iniciar() + detener() Logger + log(msg): void Conexion + conectar(): void Sesion - token: String «call» «use» «create»
11

Ejemplos Completos

Diagramas de sistemas reales que integran múltiples tipos de relaciones. Explora cada ejemplo para ver cómo se combinan en la práctica.

🛒 E-commerce🏦 Banco🎓 Universidad
Cliente - id: int - nombre: String - email: String + realizarPedido() Pedido - id: int - fecha: Date - total: double + calcularTotal() + confirmar() Producto - id: int - nombre: String - precio: double - stock: int ItemPedido - cantidad: int - precioUnit: double + getSubtotal(): double «interface» MetodoPago + procesar() + validar() TarjetaCredito 1 0..* realiza 1 1..* * 1 «use»
Relaciones usadas: Asociación (Cliente→Pedido) · Composición (Pedido◆ItemPedido) · Asociación (ItemPedido→Producto) · Dependencia «use» (Pedido→MetodoPago) · Realización (TarjetaCredito→MetodoPago)
Persona - dni: String - nombre: String - telefono: String ClienteBanco - numCliente: int - fechaAlta: Date + solicitarPrest() hereda «abstract» Cuenta - numCuenta: String - saldo: double + retirar() + depositar() CuentaAhorros - interes: double + retirar() + calcularInteres() CuentaCorriente - limite: double + retirar() + sobregiro() «interface» Transaccion + ejecutar() + revertir() + registrar() 1 0..* «use»
Relaciones usadas: Herencia (ClienteBanco→Persona) · Herencia (CuentaAhorros/CuentaCorriente→Cuenta) · Agregación (ClienteBanco◇Cuenta) · Dependencia «use» (Cuenta→Transaccion)
Facultad - nombre: String - decano: String + addCarrera() Carrera - codigo: String - nombre: String + addCurso() 1 1..* Curso - codigo: String - creditos: int + addDocente() 1 1..* «abstract» Persona - nombre: String - dni: String + getInfo(): String Estudiante Docente * * inscrito en * 1..* dicta pre-req
Relaciones usadas: Composición (Facultad◆Carrera, Carrera◆Curso) · Herencia (Estudiante/Docente→Persona) · Asociación (Estudiante↔Curso, Docente→Curso) · Asociación Reflexiva (Curso prerrequisito)
12

Quiz — Diagrama de
Clases y Relaciones

10 preguntas sobre todo lo aprendido. Retroalimentación inmediata en cada respuesta.

📝 10 preguntas⚡ Retroalimentación🏆 Puntaje final
1 / 10
Pregunta 1 de 10
0/10
📋 Resumen de notaciones UML
RelaciónNotación UMLSímbolo clavePregunta clave
DependenciaLínea punteada → (con estereotipo opcional)- - →¿Usa temporalmente?
AsociaciónLínea sólida (con o sin flecha)———¿Se conocen permanentemente?
AgregaciónLínea sólida + diamante vacío en el todo◇———¿Parte existe sin el todo?
ComposiciónLínea sólida + diamante relleno en el todo◆———¿Parte muere con el todo?
ReflexivaAsociación que vuelve a la misma clase¿Se relaciona con su mismo tipo?
HerenciaLínea sólida + triángulo vacío hacia el padre——▷¿Es un tipo de?
RealizaciónLínea punteada + triángulo vacío hacia la interfaz- - ▷¿Implementa la interfaz?