Índice

Ejercicios Unidad 16 - Abstracción

Descargar estos ejercicios

Antes de empezar

Para realizar estos ejercicios, deberás descargar los recursos del enlace de proyecto_poo_roles_abstracción. Como puedes ver, la solución está compuesta de varios proyectos. Cada uno de ellos corresponde con un ejercicio, deberás implementar todo el código, tanto de la Main como de los métodos que se piden en cada ejercicio. Cada proyecto contiene el test correspondiente, que deberás pasar para comprobar que has hecho el ejercicio correctamente.

Ejercicio 1. Abstracción en gestión de personal de cuidados

Implementa una jerarquía de clases para gestionar personal de cuidados en un centro. La clase base PersonalCuidados será no instanciable y dos subclases concretas: Enfermero y CuidadorResidencia.

Ejercicio 1: Gestión de personal de cuidados

Creando personal...

Mostrando información:
Personal: Ana Ruiz - Rol: Enfermero
 Turno: Noche
 Pacientes asignados: 12
Descripción: Supervisa y administra medicación a los pacientes.
   - Tareas asignadas:
    [08:00] Enfermero: Entrega de turno y repaso de incidencias.
    [23:00] Enfermero: Realiza ronda de control y prepara medicación nocturna.
    [03:00] Enfermero: Atiende emergencias y revisa signos vitales de pacientes críticos.
    [19:00] Enfermero: Prepara informes de pacientes y coordina con el equipo médico.;
Personal: Luis Pérez - Rol: CuidadorResidencia
 Turno: Mañana
 Habitaciones asignadas: 3
Descripción: Ayuda en las actividades diarias y acompaña a los residentes.
   - Tareas asignadas:
    [07:00] Cuidador: Ayuda en el aseo matutino.
    [15:00] Cuidador: Revisión de habitaciones y apoyo a residentes con necesidades especiales.
    [12:00] Cuidador: Asiste en la hora de la comida y supervisa la ingesta alimentaria.;

  - Gestión de turno a las 23:00:
[23:00] Enfermero: Realiza ronda de control y prepara medicación nocturna.
[15:00] Cuidador: Revisión de habitaciones y apoyo a residentes con necesidades especiales.

  - Gestión de turno a las 15:00:
[08:00] Enfermero: Entrega de turno y repaso de incidencias.
[15:00] Cuidador: Revisión de habitaciones y apoyo a residentes con necesidades especiales.

Presiona cualquier tecla para salir...

«Record»TareaTurnoHora: TimeSpanDescripcion: stringPersonalCuidados-Nombre: string-Turno: string+TareasTurno: List<TareaTurno>+PersonalCuidados(nombre: string, turno: string)+GetNombre(): string+GetTurno(): string+AñadeTareaTurno(hora: TimeSpan, descripcion: string):void {abstract}+AñadeTareaTurno(tareaTurno: TareaTurno):void {abstract}+DescripcionRol(): string {abstract}+{virtual} GestionaTurno(horaActual: DateTime): string+^ToString(): stringEnfermero-PacientesAsignados: int {readonly}+Enfermero(nombre: string, turno: string, pacientesAsignados: int)+GetPacientesAsignados(): int+^AñadeTareaTurno(hora: TimeSpan, descripcion: string):void+^AñadeTareaTurno(tareaTurno: TareaTurno):void+^DescripcionRol(): string+^ToString(): stringCuidadorResidencia-HabitacionesAsignadas: int {readonly}+CuidadorResidencia(nombre: string, turno: string, habitacionesAsignadas: int)+GetHabitacionesAsignadas(): int+^AñadeTareaTurno(hora: TimeSpan, descripcion: string):void+^AñadeTareaTurno(tareaTurno: TareaTurno):void+^DescripcionRol(): string+^ToString(): string

Requisitos

Algunos de los elementos más específicos que se tienen que implementar son:

Ejercicio 2. Abstracción en gestión de agenda de horarios

Implementa una jerarquía de clases para gestionar una agenda de horarios usando un union type para el rango temporal del evento.

Ejercicio 2: Gestión de agenda de horarios

Creando eventos...

Evento: CitaMedica

  - Evento -> Desde: 2025-09-10 09:30, Hasta: 2025-09-10 10:00 -  Cita Médica: Consulta Cardiología - Horario específico
    Dirección: Av. de la Salud, 15

  - Evento -> Desde: 2025-09-10 00:00, Hasta: 2025-09-10 23:59 -  Reunión: Reunión de proyecto - Todo el día
    Asistentes: Ana, Juan, Marta

  - Evento -> Desde: 2025-09-01 00:00, Hasta: 2025-10-01 00:00 -  Cita Médica: Consulta Revisión mensual - Todo el mes
    Dirección: C/ Mayor, 22

Presiona cualquier tecla para salir...

Requisitos:

El union type debe implementarse como un record abstracto RangoEvento con variantes:

La clase base abstracta EventoAgenda debe tener:

Debes crear al menos dos concreciones:

En la clase Program, implementa un método GestionaEventos que permita crear eventos de diferentes tipos (CitaMedica y ReunionTrabajo) usando las tres variantes de RangoEvento (HorarioEspecifico, TodoElDia, TodoElMes).

Ejercicio 3. Validación de formularios con records y clases abstractas

En este ejercicio trabajarás con el patrón de validación usando records y clases abstractas. Utiliza como base el ejemplo del tema:

public abstract record Validacion
{
    public record Exito() : Validacion;
    public record Error(string Mensaje) : Validacion;
}

public static class Validador
{
    public static Validacion ValidaDni(string dni) =>
        !string.IsNullOrWhiteSpace(dni) && dni.Length == 9
            ? new Validacion.Exito()
            : new Validacion.Error("El DNI debe tener 9 caracteres.");

    public static Validacion ValidaNombre(string nombre) =>
        !string.IsNullOrWhiteSpace(nombre)
            ? new Validacion.Exito()
            : new Validacion.Error("El nombre no puede estar vacío.");

    public static Validacion ValidaFechaNacimiento(DateTime fecha) =>
        fecha < DateTime.Today.AddYears(-10)
            ? new Validacion.Exito()
            : new Validacion.Error("La fecha de nacimiento no es válida.");
}
Ejercicio 3: Validación de formularios

Para las entradas de datos...
Estudiante: DNI=12345678A, Nombre=Ana Ruiz, FechaNacimiento=10/05/2005, Estudios=Informática
    Validación: INCORRECTO -> Los estudios no están definidos
  
Estudiante: DNI=, Nombre=Pedro, FechaNacimiento=10/05/2005, Estudios=DAM
    Validación: INCORRECTO -> El DNI debe tener 9 caracteres.
  
Profesor: DNI=87654321B, Nombre=Luis Pérez, FechaNacimiento=20/11/1980, Especialidad=Matemáticas, Departamento=FISC
    Validación: CORRECTO -> El profesor Luís Pérez con DNI: 87654321B y de la especialidad de matemáticas 'ha sido añadido al sistema'.

Presiona cualquier tecla para salir...

Requisitos:

En el programa principal, crea un método GestionaFormularios para crear una lista de formularios con objetos de ambos tipos, muestra la información y el resultado de la validación de cada uno.

Ejercicio 4. Interfaces: Gestión de sesiones deportivas y clonación

En este ejercicio crearás una interfaz propia junto con la implementación de IComparable para modelar sesiones de entrenamiento de distintos deportes.

Ejercicio 4: Interfaces y entrenamiento

Creando sesiones...

Mostrando Sesiones realizadas...
Sentadillas (Basica) - Duración: 20 min
  Intensidad: 6
  Calorías estimadas: 157,00 kcal
  Fecha: 2025-09-10

Sentadillas (Peso) - Duración: 25 min
  Intensidad: 8
  Calorías estimadas: 267,00 kcal
  Fecha: 2025-09-10

Running - Duración: 45 min
  Intensidad: 4 - Distancia: 7,5 km
  Calorías estimadas: 291,00 kcal
  Fecha: 2025-09-11

Comparaciones:
  Sentadillas (Peso) vs Sentadillas (Basica): > (mayor gasto calórico)

Presiona cualquier tecla para continuar...

Requisitos:

Ejercicio 5. Sistema de reprodución de audio

Vamos a diseñar las clases para un posible sistema operativo de una antigua radio de coche con DAB (Digital Audio Broadcasting) y un reproductor de CD.

En el programa principal copiaremos el siguiente código a completar, que nos permitirá deducir funcionalidades:

public static void Main() {
    string[] canciones = {
        "Wanna Be Startin' Somethin", "Baby Be Mine", "The Girl Is Mine", "Thriller", "Beat It",
        "Billie Jean", "Human Nature", "P.Y.T. (Pretty Young Thing)", "The Lady in My Life"};           
    Disc thriller = new Disc("Thriller", "Michael Jackson", canciones);
    DABRadioCD radioCD = new DABRadioCD();
    ConsoleKeyInfo tecla = new ConsoleKeyInf();
    do {
        try {
            Console.WriteLine(radioCD.MessageToDisplay);
            tecla = Console.ReadKey(true);
            Console.Clear();
            switch (tecla.KeyChar) {
                ...
                case '7':
                    radioCD.InsertCD = thriller;
                break;
                ...
            }
        }
        catch (Exception e) {
            Console.WriteLine(e.Message);
        }
} while (tecla.Key != ConsoleKey.Escape);

Además de implementar el diagrama de clases siguiente:

IMediaMessageToDisplay : stringPlay() : voidStop() : voidPause() : voidNext() : voidPrevious() : voidGetMessageToDisplay() : string«enumerable»MediaStateStopped,Paused,Playing,Disc-Album : string-Artist : string-Songs : string[]/+ NumTracks : int «get»-GetAlbum(): string-SetAlbum(album:string)-GetArtist(): string-SetArtist(artist:string)-GetSongs(): string[]-SetSongs(songs:string[])+NombreCancion(in int:song):string+Disc(album:string, artist:string, songs:string[])+^ToString() : stringCDPlayer-Track : ushort-State : MediaState-MediaIn : bool+CDPlayer()-GetTrack(): ushort-SetTrack(track:ushort)-GetState(): MediaState-SetState(state: MediaState)+GetMediaIn(): bool+InsertMedia(media:Disc) : void+ExtractMedia() : boolDABRadio«const» SEEK_STEP : float = 0.5f«const» MAX_FREQUENCY : float = 108f«const» MIN_FRECUENCY : float = 87.5f-Frequency : float-State : MediaState+DABRadio()DABRadioCD-ActiveDevice : IMedia+InsertCD : Disc+DABRadioCD()+SetInsertCD(disc: Disc)-GetActiveDevice(): IMedia-SetActiveDevice (acitveDevice: ActiveDevice)-GetFrecuencia(): float-SetFrecuencia(frecuencia:float)-GetState(): MediaState-SetState(mediaState:MediaState)+ExtractCD() : void+SwitchMode() : void1111«reproduce»10..1«use»«use»

MODO: CD
STATE: PLAYING... Album: Thriller Artist: Michael Jackson. Track 3 - The Girl Is Mine
[1]Play [2]Pause [3]Stop [4]Prev [5]Next [6]Switch [7]Insert CD [8]Extract CD, [ESC]Turn off

Requisitos:
Que completaremos con las siguientes funcionalidades.

Tendremos una clase DABRadioCD que estará compuesta por dos dispositivos un reproductor de CD y un sintonizador DAB.

En el reproductor de CD además podremos tener un Compat Disc® representado por la clase Disc.

📌 Nota: Recuerda que en C# los Get (Accesores), Set (Mutadores) son Propiedades y que los campos se pueden implementar a través de Propiedades Autoimplementadas.