Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Práctica Obligatoria
Curso 2018/2019
Índice general
1. Introducción 2
1.1. Descripción general de la práctica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
2. Etapa 1 4
2.1. ETAPA 1.1 Orientación a Objetos: La clase Abono . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.1.1. Objetivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.1.2. Requisitos previos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.1.3. Enunciado: Implementación de la clase Abono . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.1.4. Familiarización con el entorno BlueJ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.2. ETAPA 1.2 Ejecución de Aplicaciones: La clase Principal . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.2.1. Objetivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.2.2. Requisitos previos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.2.3. Enunciado: Creación de una clase Lanzador . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
3. ETAPA 2 7
3.1. ETAPA 2.1: Uso de la composición . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
3.1.1. Objetivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
3.1.2. Requisitos previos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
3.1.3. Enunciado: Creación de la clase Gestor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
3.2. ETAPA 2.2: Validando abonos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
3.2.1. Objetivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
3.2.2. Requisitos previos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
3.2.3. Enunciado . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
4. ETAPA 3 11
4.1. ETAPA 3.1: Uso de la herencia y polimorfismo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
4.1.1. Objetivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
4.1.2. Requisitos previos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
4.1.3. Enunciado: Añadiendo abonos de tipo anual. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
4.2. ETAPA 3.2: Extendiendo la funcionalidad del sistema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
4.2.1. Objetivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
4.2.2. Requisitos previos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
4.2.3. Enunciado . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
6. Apéndices 16
1
Introducción
La práctica se realizará utilizando Java como lenguaje de programación orientado a objetos. El primer concepto que se
debe conocer es el de objeto, el ladrillo con el que se construye un progama bajo este paradigma de programación. Los objetos
tienen vida cuando nuestro programa está en ejecución, y pueden relacionarse entre si de diversas maneras, proporcionando
al programador las funcionalidades necesarias para resolver una amplia gama de problemas.
La definición de un objeto viene dada por lo que se conoce como clase, siendo ésta la entidad que en realidad diseñaremos
y programaremos, en términos de sus campos o atributos y métodos. Estos campos y métodos nos permiten definir las
caracterı́sticas y funcionalidades de la clase. Una vez definida, a partir de la clase podremos crear objetos, que son los que en
realidad llevarán a cabo la funcionalidad de nuestro programa en tiempo de ejecución.
Por tanto, podemos ver los objetos como los componentes que nos servirán para diseñar nuestro programa, y las clases como
las definiciones de dichos objetos. Una misma clase puede por tanto dar lugar a muchos objetos diferentes, cada uno con
caracterı́sticas diferentes que vendrán dadas por los valores de sus campos.
Es conveniente hacer una primera lectura completa de este documento para tener una visión global de lo que se
pide, y organizar apropiadamente el estudio de la asignatura.
2
Descripción general de la práctica
Para facilitar la realización de la práctica, dar un criterio de autoevaluación y homogeneizar la corrección por parte de
los tutores, en cada fase se indicará un conjunto de llamadas (creación de objetos y llamadas a métodos) a los que el sistema
deberá responder, ası́ como la salida esperada. Es importante tener en cuenta que la implementación debe ajustarse a la
definición de objetos y métodos (tipo y número de atributos) invocados en los ejemplos, de forma que los tutores puedan
evaluar todas las prácticas mediante el mismo lote de llamadas.
Por otro lado, cuando afrontamos el desarrollo de una aplicación informática es indispensable y necesario realizar una fase
previa donde se analicen los requisitos y se diseñen las clases necesarias para llevar a cabo las funcionalidades requeridas,
ası́ como la relación entre las mismas. Para ello, antes de comenzar a implementar cada una de las etapas en las que ha sido
dividida la práctica, se debe realizar una lectura completa de la etapa a abordar, realizando un diagrama de clases donde se
representen las clases necesarias, con sus atributos y métodos, y las relaciones entre las clases, para posteriormente comenzar
la fase de implementación de las mismas. El diagrama de clases obtenido en la última etapa debe ser entregado junto al
código de la práctica.
3
Etapa 1
DNI, representando el número y letra del documento nacional de identidad del usuario.
Año de nacimiento, atributo que indica el año de nacimiento, necesario para estimar el precio de un abono.
Familia numerosa, indicando si el usuario dispone o no del carnet de familia numerosa con vistas a los descuentos
en el precio del abono.
Zona tarifaria, indicando la zona tarifaria a la que está adscrito el abono. Asumiremos que existe un conjunto
predefinido de zonas tarifarias: {A1, A2, B1, B2,C}. Dado que asumimos que existe un conjunto predefinido de zonas,
éstas deberán implementarse como un tipo enumerado.
4
ETAPA 1.1 Orientación a Objetos: La clase Abono
Fecha de caducidad. Para ello usaremos la clase Calendar del paquete java.Util (Ver apéndice del documento o
https://docs.oracle.com/javase/7/docs/api/java/util/Calendar.html)
Además, todo objeto de la clase Abono debe permitir consultar y modificar todos estos campos a través de una serie de
métodos creados a tal efecto: por cada atributo debe haber dos métodos, uno para consultar su valor y otro para modificarlo.
Por ejemplo, para el campo nombre tendremos los métodos getNombre() y setNombre() para consultar su valor y modi-
ficarlo, respectivamente. Finalmente, la clase Abono dispondrá de un método que imprima en pantalla toda su información,
incluyendo DNI, nombre, apellidos, fecha de caducidad, zona tarifaria, fecha de nacimiento y si el abonado tiene familia
numerosa.
RECOMENDACIÓN: jugar con BlueJ creando objetos de la clase Abono, modificando el valor de sus atributos,
mostrándolos por pantalla, etc.
BlueJ nos permite ejecutar nuestras aplicaciones mediante la invocación de los métodos de sus objetos, pero no es ésta la
única manera de hacerlo. Java, más allá de BlueJ, nos permite ejecutar los programas que creamos de forma independiente. A
estas alturas sabemos que cada clase dispone de una serie de métodos y campos, que son propios de los objetos que creamos
a partir de dicha clase, es decir, que para poderlos utilizar necesitamos crear primero un objeto. Por ejemplo, la clase Abono
que deberemos crear en esta práctica, tendrá métodos para consultar datos como el nombre del abonado o la zona tarifaria,
que sólo podrán ser invocados una vez tengamos creado algún objeto de esta clase. Pues bien, existe otro tipo de métodos
que no son propios de los objetos, sino de las clases. De esta forma, no necesitamos una instancia particular de la clase para
invocarlos. La ejecución fuera de BlueJ comienza sin que exista ningún objeto (en BlueJ primero se creaban objetos que se
almacenan en el banco de objetos para posteriormente invocar sus métodos). Antes de tener objetos, lo único que tenemos son
5
Fundamentos de Informática. Práctica Obligatoria. Etapa 1
las clases que los definen, por lo que deberemos usar un método de clase para poder iniciar la ejecución de nuestro programa.
Un caso particular de estos métodos de clase es el método main(), que es el que se utiliza como punto de partida para iniciar
la ejecución de un programa en Java (véase el apartado 2.2.2).
RECOMENDACIÓN: Al final de este apartado deberı́a entender la diferencia entre ejecutar un programa en BlueJ y
hacerlo de forma independiente, esto es, por ejemplo, ejecutarlo desde la lı́nea de comandos (sı́mbolo de sistema en
Windows/Linux/MacOS).
NOTA IMPORTANTE: La presente práctica debe poderse ejecutar independientemente de BlueJ de cara a su
entrega y corrección.
6
ETAPA 2
Nuestra aplicación va a gestionar un conjunto de abonos transporte, que hemos modelado como una clase. Estos abonos se
gestionarán por medio de una clase Gestor. Los sucesos que queremos modelar mediante esta clase son los siguientes:
Para poder modelar este problema, la clase Gestor tendrá las siguientes caracterı́sticas:
1. La clase contiene una lista de abonos, es decir, todos aquellos abonos que han sido dados de alta en el sistema.
7
Fundamentos de Informática. Práctica Obligatoria. ETAPA 2
2. La clase gestor dispone de un método que permite dar de alta un nuevo abono, es decir, añadir al sistema un objeto
de la clase abono. La fecha inicial de caducidad será anterior a la fecha actual, de forma que hasta que el abono no
sea recargado, el usuario no podrá hacer uso de éste. Tras dar de alta un nuevo abono, el sistema deberá imprimir en
pantalla los datos del abono dado de alta. En nuestro escenario, un mismo usuario no puede tener más de un abono. Por
tanto, el sistema deberá comprobar que no haya ya dado de alta un abono con el mismo DNI. Si lo hay, se imprimirá
en pantalla un mensaje indicándolo.
3. Mediante otro método, la clase gestora deberá imprimir en pantalla el precio de recarga de un determinado abono dado
el DNI del usuario. Si no existe en el sistema ningún abono asociado a ese DNI, se imprimirá en pantalla un mensaje
indicándolo. Para el cálculo de la tarifa, el sistema tendrá de una tarifa base que podrá actualizarse o consultarse.
La tarifa de un abono se calculará de la siguiente forma: El precio de las zonas tarifarias A1,A2,B1,B2 y C será un
100 %,125 %, 150 %, 200 % y 300 % de la tarifa base respectivamente. Además, en caso de que el usuario tenga familia
numerosa o tenga menos de 18 años, ésta se reduce en un 50 %.
4. Dado un DNI asociado a un abono, la clase gestora permitirá recargar un abono, es decir, actualizar la fecha de
caducidad a un mes después de la fecha actual. En caso de que no exista un abono con dicho DNI, el sistema lo
notificará imprimiendo en pantalla un mensaje. En caso de que aun no haya vencido el abono, la fecha se actualizará
igualmente a un mes después de la fecha actual. Finalmente, el sistema imprimirá en pantalla un mensaje indicando
que el abono ha sido recargado y la nueva fecha de caducidad.
NOTA IMPORTANTE: En esta fase es crucial tener en cuenta el concepto de encapsulación. La clase gestora se encarga
de mantener la lista de abonos existentes y la tarifa base. Sin embargo, adelantamos que en fases posteriores surgiran otros
tipos de abonos con otras caracterı́sticas. Los elementos comunes a cualquier tipo de abono que pueda surgir en el futuro
es que tendrán un precio de recarga dependiente de la tarifa base y una fecha de caducidad, pudiendo variar los criterios
de cálculo del precio, la información empleada para ese cálculo, el tiempo de caducidad o la impresión en pantalla de la
información asociada al abono. En términos de programación orientada a objetos, esto implica que el cálculo del precio debe
encapsularse en la propia clase Abono añadiendo en esta clase los métodos que sean necesarios.
En esta etapa se deben documentar todas las clases creadas hasta ahora. En capı́tulo 6, concretamente en la sección 6.11 se
describe los pasos a seguir para documentar las clases correctamente.
Por último, vamos a modificar ahora el método main() de la clase Lanzador para dar de alta y recargar abonos. El sistema
deberı́a ser capaz de responder al siguiente código implementado en la clase Lanzador:
Gestor g=new Gestor();
g.actualizaTarifaBase(10);
Abono a=new Abono();
Zona z=Zona.A1;
Date d=new Date(118,5,2,0,0,0);
a.setNombre(‘‘Federico’’);
a.setApellidos(‘‘Garcia Lopez’’);
a.setDNI(‘‘43815923F’’);
a.setFamiliaNumerosa(true);
a.setAnyoNacimiento(1974);
a.setFechaCaducidad(d);
a.setZona(z);
g.anyadirAbono(a);
g.imprimeImporte(‘‘43815923’’);
g.imprimeImporte(‘‘54353543L’’);
g.recargarAbono(‘‘43815923F’’);
8
ETAPA 2.2: Validando abonos
3.2.3. Enunciado
En esta etapa vamos a ampliar el sistema para que en cada estación se valide el abono del usuario en el momento que
accede o sale de una estación. Para ello, el sistema deberá gestionar un conjunto de estaciones de tren, pudiendo añadir nuevas
estaciones al sistema, de la misma forma que el sistema gestiona el conjunto de abonos dados de alta. Una estación lleva por
nombre la localidad o distrito donde se encuentra y le corresponde una zona tarifaria. Para satisfacer los requisitos del sistema,
la clase Estación deberá disponer de un método que valide un abono, imprimiendo en pantalla si el abono es válido o no.
Esta respuesta dependerá de dos factores: si el abono está dado de alta y recargado, y también si la zona que cubre el abono
incluye la zona tarifaria de la estación. Es importante tener en cuenta que las zonas tarifarias se incluyen unas dentro de otras.
Por ejemplo, un abono asociado a la zona B2 permite viajar por cualquier estación de las zonas A1, A2, B1 o B2. Como
detalle de implementación, para abordar esto se puede hacer uso del método ordinal del tipo enumerado que devuelve un
entero con la posición del valor dentro del enumerado. Por ejemplo Zona.A2.ordinal() devolverı́a el valor 1.
Como prueba, debe implementar en la clase Lanzador las siguientes llamadas y comprobar su correcto funcionamiento:
Gestor g=new Gestor();
g.actualizaTarifaBase(10);
Abono a=new Abono();
Zona z=Zona.A2;
a.setZona(z);
a.setNombre(‘‘Federico’’);
a.setApellidos(‘‘Garcı́a López’’);
a.setDNI(‘‘43815923F’’);
a.setFamiliaNumerosa(false);
a.setAnyoNacimiento(1974);
g.anyadirAbono(a);
g.recargarAbono(‘‘43815923F’’);
Estacion e1=new Estacion();
Estacion e2=new Estacion();
e1.setLocalidad(‘‘Madrid-Atocha’’);
e1.setZona(Zona.A1);
e2.setLocalidad(‘‘San Rafael’’);
e2.setZona(Zona.B2);
g.anyadirEstacion(e1);
g.anyadirEstacion(e2);
e1.validarAbono(a);
e2.validarAbono(a);
1. Indicar que ha sido dado de alta un abono e imprimir en pantalla la información relativa a dicho abono.
2. Imprimir en pantalla un mensaje indicando que el abono asociado al DNI ”43815923F”ha sido recargado y su nueva
fecha de caducidad.
3. Imprimir en pantalla un mensaje indicando cada una de las estaciones que se han añadido al sistema.
4. Imprimir en pantalla un mensaje indicando que el abono con DNI 43815923F es válido para la estación Madrid-Atocha.
9
Fundamentos de Informática. Práctica Obligatoria. ETAPA 2
5. Imprimir en pantalla un mensaje indicando que el abono con DNI 43815923F NO es válido para la estación de San
Rafael.
De nuevo, es importante hacer más pruebas con diferentes objetos y atributos.
10
ETAPA 3
11
Fundamentos de Informática. Práctica Obligatoria. ETAPA 3
a1.setAñoNacimiento(2010);
g.añadirAbono(a1);
g.imprimeImporte(‘‘42523435A’’);
g.recargarAbono(‘‘42523435A’’);
Abono a2=new AbonoAnual();
Zona z2=Zona.B2;
a2.setZona(z2);
a2.setNombre(‘‘Pepe’’);
a2.setApellidos(‘‘Garcı́a González’’);
a2.setDNI(‘‘5283843G’’);
a2.setFamiliaNumerosa(false);
a2.setAñoNacimiento(2004);
g.añadirAbono(a2);
g.imprimeImporte(‘‘5283843G’’);
g.recargarAbono(‘‘5283843G’’);
Estacion e1=new Estacion();
Estacion e2=new Estacion();
e1.setLocalidad(‘‘Madrid-Atocha’’);
e1.setZona(Zona.A1);
e2.setLocalidad(‘‘San Rafael’’);
e2.setZona(Zona.B2);
g.añadirEstacion(e1);
g.añadirEstacion(e2);
e1.validarAbono(a1);
e2.validarAbono(a1);
e1.validarAbono(a2);
e2.validarAbono(a2);
12
ETAPA 3.2: Extendiendo la funcionalidad del sistema
4.2.3. Enunciado
Para abordar esta etapa tendremos que incluir un método en la clase gestor que, dado dos nombres de estación, devuelva
la zona mı́nima a la que tiene que estar abonado el usuario. Algunas consideraciones respecto a este método son:
El método debe tomar como parámetros de entrada dos nombres de estación (localidad o distrito).
En caso de una de las dos estaciones no exista en el sistema, se imprime un mensaje indicándolo.
En caso de que si existan, el método debe imprimir en pantalla la zona más amplia de las dos. Por ejemplo, si las dos
estaciones se encuentran en las zonas A2 y C respectivamente, el método deberı́a imprimir la zona C.
Recordamos que para este método se puede hacer uso de los métodos toString y ordinal del tipo enumerado en Java.
Como prueba, debe implementar en la clase Lanzador las siguientes llamadas y comprobar su correcto funcionamiento:
13
Fechas y normas de entrega
5.1. Fechas
La realización de la práctica se llevará a cabo en los centros asociados, siendo las sesiones organizadas y supervisadas por
el tutor de la asignatura. Habrá como mı́nimo tres sesiones presenciales de obligatoria asistencia. En cada sesión se abordará
cada una de las partes de las que consta la práctica. Los alumnos deberán ponerse en contacto con su centro asociado
para informarse acerca de cuándo tendrán que asistir a las sesiones.
Las fechas orientativas para la realización de cada una de las etapas serán:
Una memoria de no más de 6 hojas donde se explique la especificación y el diseño (etapa 0, ver ??) realizados en cada
parte de la práctica.
Los ficheros .java, sin caracteres especiales; por ejemplo “ñ” o tildes.
NOTA IMPORTANTE: Los nombres de los ficheros y carpetas/paquetes que compongan la práctica entregada, deben con-
tener SÓLO caracteres correspondientes a las letras de la A a la Z, tanto mayúsculas como minúsculas, números del 0 al 9 y
los caracteres especiales ’-’ y ’ ’. No deben utilizarse otros, tales como tildes o sı́mbolos.
Los tutores de la asignatura deberán evaluar las prácticas en el entorno virtual antes del 17 de Mayo.
NOTA IMPORTANTE: Los tutores tienen que cumplir una serie de requisitos ante los alumnos debido a que la práctica
cuenta para la calificación de la asignatura. Por tanto, antes de entregar las calificaciones al equipo docente deberán:
1. Publicar la nota de las prácticas en un lugar accesible para los alumnos (ya sea vı́a web o mandar un fax al centro
asociado)
2. Establecer un dı́a de revisión de prácticas (previo al perı́odo de entrega de las calificaciones al equipo docente), dado
que éstas forman parte de la evaluación del alumno.
Es importante que se mantengan todos los identificadores definidos en el enunciado, es decir, el nombre de las clases, atributos
y métodos deben ser tal y como se definen en este enunciado.
14
Evaluación de la práctica
15
Apéndices
16