Ir al contenido principal

Entornos de Desarrollo - Unidad 5 - Sesión 3: Relaciones en los Diagramas de Clases (Herencia, Composición y Agregación)

Objetivos de la sesión

  1. Comprender las relaciones avanzadas en los diagramas de clases: herenciacomposición y agregación.
  2. Implementar estas relaciones en código Java.
  3. Aprender a identificar el tipo de relación en una descripción textual.

Estructura de la sesión

1. Explicación teórica (40 minutos)


Herencia

  • Definición:
    Relación en la que una clase hija (o subclase) hereda atributos y métodos de una clase padre (o superclase). Permite reutilizar código y crear jerarquías de clases.

    • Ejemplo: "Un Estudiante es un tipo de Persona."
  • Notación:
    Una flecha con un triángulo hacia la superclase:

    Estudiante --------|> Persona
  • Traducción a código:
    Se usa la palabra clave extends.

    public class Persona { public String nombre; public int edad; public void mostrarInformacion() { System.out.println("Nombre: " + nombre + ", Edad: " + edad); } } public class Estudiante extends Persona { public int numeroMatricula; public void estudiar() { System.out.println(nombre + " está estudiando."); } }

Composición

  • Definición:
    Relación "es parte de" donde una clase contiene a otra como parte integral. Si la clase contenedora se destruye, también se destruyen las partes.

    • Ejemplo: "Un Coche tiene un Motor. Si el coche desaparece, el motor también."
  • Notación:
    Un rombo negro en el lado de la clase contenedora:

    Coche ◆--------- Motor
  • Traducción a código:
    La clase contenedora tiene la clase parte como atributo y la instancia se crea dentro de la clase contenedora.

    public class Motor { public void encender() { System.out.println("El motor está encendido."); } } public class Coche { private Motor motor; public Coche() { this.motor = new Motor(); // Se crea el motor al crear el coche } public void arrancar() { motor.encender(); System.out.println("El coche está en marcha."); } }

Agregación

  • Definición:
    Relación "tiene un" donde una clase contiene a otra, pero las partes pueden existir independientemente del todo.

    • Ejemplo: "Un Profesor tiene Estudiantes, pero los estudiantes pueden existir sin el profesor."
  • Notación:
    Un rombo vacío en el lado de la clase contenedora:

    Profesor ◇--------- Estudiante
  • Traducción a código:
    La clase contenedora tiene la clase parte como atributo, pero la instancia se pasa desde fuera.

    public class Estudiante { public String nombre; } public class Profesor { private Estudiante[] estudiantes; public Profesor(Estudiante[] estudiantes) { this.estudiantes = estudiantes; } public void mostrarEstudiantes() { for (Estudiante estudiante : estudiantes) { System.out.println("Estudiante: " + estudiante.nombre); } } }

2. Ejercicios prácticos (2-2.5 horas)


Ejercicio 1: Herencia (Clase Vehículo)

Descripción:
Modelar una jerarquía de clases para vehículos.

  • La clase base será Vehiculo, con los atributos: marca y modelo.
  • Habrá dos subclases:
    • Coche tendrá un atributo adicional: numeroPuertas.
    • Moto tendrá un atributo adicional: tipoManillar.
  • Cada clase debe tener un método mostrarInformacion() que muestre sus datos.

Tareas para los estudiantes:

  1. Diseñar un diagrama de clases.
  2. Implementar las clases en Java.
  3. Crear un programa que instancie objetos de cada clase y muestre su información.

Solución para el profesor:

  • Diagrama de clases:

    ----------------------- | Vehiculo | ----------------------- | + marca: String | | + modelo: String | ----------------------- | + mostrarInformacion(): void | ----------------------- ^ ^ | | ----------------- ----------------- | Coche | | Moto | ----------------- ----------------- | + numPuertas: int | + tipoManillar: String | ----------------- ----------------- | + mostrarInformacion(): void | ----------------- -----------------
  • Código en Java:

    public class Vehiculo { public String marca; public String modelo; public void mostrarInformacion() { System.out.println("Marca: " + marca + ", Modelo: " + modelo); } } public class Coche extends Vehiculo { public int numeroPuertas; @Override public void mostrarInformacion() { super.mostrarInformacion(); System.out.println("Número de puertas: " + numeroPuertas); } } public class Moto extends Vehiculo { public String tipoManillar; @Override public void mostrarInformacion() { super.mostrarInformacion(); System.out.println("Tipo de manillar: " + tipoManillar); } } public class Main { public static void main(String[] args) { Coche coche = new Coche(); coche.marca = "Toyota"; coche.modelo = "Corolla"; coche.numeroPuertas = 4; Moto moto = new Moto(); moto.marca = "Yamaha"; moto.modelo = "MT-07"; moto.tipoManillar = "Deportivo"; coche.mostrarInformacion(); moto.mostrarInformacion(); } }

Ejercicio 2: Composición y Agregación (Coche y Ruedas)

Descripción:

  • Un Coche tiene 4 ruedas (Rueda) como parte integral (composición).
  • Además, el coche tiene un Propietario que puede existir independientemente (agregación).

Tareas para los estudiantes:

  1. Diseñar el diagrama de clases.
  2. Implementar las clases en Java.
  3. Crear un programa que:
    • Cree un coche con 4 ruedas y un propietario.
    • Muestre la información del coche, sus ruedas y su propietario.

Solución para el profesor:

  • Diagrama de clases:

    ----------------------- | Coche | ----------------------- | + marca: String | | + ruedas: Rueda[] | | + propietario: Persona | ----------------------- | + mostrarInformacion(): void | ----------------------- ◆ ◇ | | ---------------- ---------------- | Rueda | | Persona | ---------------- ---------------- | + tipo: String | | + nombre: String | ---------------- ----------------
  • Código en Java:

    public class Rueda { public String tipo; public Rueda(String tipo) { this.tipo = tipo; } } public class Persona { public String nombre; public Persona(String nombre) { this.nombre = nombre; } } public class Coche { public String marca; private Rueda[] ruedas; public Persona propietario; public Coche(String marca, Persona propietario) { this.marca = marca; this.propietario = propietario; this.ruedas = new Rueda[] { new Rueda("Delantera izquierda"), new Rueda("Delantera derecha"), new Rueda("Trasera izquierda"), new Rueda("Trasera derecha") }; } public void mostrarInformacion() { System.out.println("Marca: " + marca); System.out.println("Propietario: " + propietario.nombre); System.out.println("Ruedas:"); for (Rueda rueda : ruedas) { System.out.println("- " + rueda.tipo); } } } public class Main { public static void main(String[] args) { Persona propietario = new Persona("Juan Pérez"); Coche coche = new Coche("Ford Mustang", propietario); coche.mostrarInformacion(); } }

3. Resumen y preguntas finales (15-20 minutos)

  1. Repaso de conceptos clave:

    • Diferencias entre herencia, composición y agregación.
    • Cómo identificar cada relación en una descripción textual.
  2. Preguntas para la reflexión:

    • ¿Qué sucede si eliminamos la clase contenedora en una composición? ¿Y en una agregación?
    • ¿Cuándo usarías herencia en lugar de composición?
  3. Avance para la próxima sesión:

    • Relación entre diagramas de clases y generación de código automáticamente con herramientas de modelado.

Apuntes del profesor

  • Material necesario: Pizarra, hojas de diagramas, editor de código.
  • Tiempo estimado por ejercicio:
    • Ejercicio 1: 60 minutos.
    • Ejercicio 2: 75-90 minutos.
  • Consejo: Supervisar especialmente la traducción de los diagramas a código, asegurándose de que entiendan cómo implementar correctamente los constructores y relaciones.

Comentarios