Solemne2

  • November 2019
  • PDF

This document was uploaded by user and they confirmed that they have the permission to share it. If you are author or own the copyright of this book, please report to us by using this DMCA report form. Report DMCA


Overview

Download & View Solemne2 as PDF for free.

More details

  • Words: 2,621
  • Pages: 11
Práctica 8: Herencia, Interfaces y Polimorfismo Ingeniería de Telecomunicación Curso 2005/2006 17 de enero de 2005 1. 2. 3. a. b. 4. 5.

Objetivo de la práctica........................................................................................................... 1 Ejercicio 1: La clase Banco ................................................................................................... 1 Ejercicio 2: La aplicación cálculo de hipotecas..................................................................... 4 Herencia................................................................................................................................. 5 Interfaces ............................................................................................................................... 7 Evaluación ........................................................................................................................... 10 Normas de entrega ............................................................................................................... 11

1. Objetivo de la práctica Esta práctica tiene como objetivo consolidar los conceptos de herencia, interfaces y polimorfismo en Java. Tras la realización de esta práctica, el alumno deberá ser capaz de:  

Comprender las relaciones entre clases y las decisiones de diseño tomadas para la resolución del problema. Implementar las clases y sus relaciones en programas Java.

2. Ejercicio 1: La clase Banco El punto de partida será la realización de una aplicación que permita calcular hipotecas. Para ello, se desea modelar e implementar el siguiente sistema: 

Un banco concede hipotecas a sus clientes, por las cuales les cobra una serie de cuotas periódicas. La cuenta de cargo de las cuotas es siempre una cuenta asociada abierta en el mismo banco que concede la hipoteca. Además, un cliente puede tener varias hipotecas en el banco, incluso asociadas a la misma cuenta (una para el piso y otra para la plaza de garaje, por ejemplo).



De cada cliente se desea conocer su NIF, su nombre y apellidos.



Las cuentas están asociadas a un solo cliente (su titular) y están identificadas por un código de cuenta de 20 dígitos (4 para el código de entidad, 4 para el número de sucursal, 2 dígitos de control y 10 dígitos para el número de cuenta). Además se necesita conocer el saldo de la cuenta para descontar las cuotas de la hipoteca.



Las hipotecas que los clientes contratan están asociadas a una cuenta de cargo y tienen un identificador con la misma estructura que el número de cuenta.



Cuando se da de alta una hipoteca se proporciona valor a esos atributos, así como a los atributos siguientes: • importe inicial del préstamo pendiente de amortizar (deuda primaria) • tasa de interés anual que se pagará • duración de la hipoteca en número de años

Además, cada hipoteca posee importePendiente y numPeriodosAmortizados que guardan el estado actual de la hipoteca (esto es, la deuda pendiente y los meses que quedan para poder cancelar la hipoteca). Se proponemos el diseño de clases de la Figura 1 para modelar el sistema bancario pedido.

Figura 1 Diseño de clases UML

La implementación en Java de la clase Cliente sería la siguiente: /** * Clase Cliente. */ class Cliente { private String nif; private String nombre; private String apellidos; public Cliente (String nif, String nombre, String apellidos){ this.nif = …; this.nombre = …; this.apellidos = …; } public String getNif (){

return this.nif; } public String getNombre (){ return this.nombre; } public String getApellidos (){ return this.apellidos; } public void setNif (String nif){ this.nif = nif; } public void setNombre (String nombre){ this.nombre = nombre; } public void setApellidos (String apellidos){ this.apellidos = apellidos; } }

La implementación en Java de la clase Cuenta sería la siguiente: /** * Clase Cuenta. */ class Cuenta { private String codigo; private double saldo; private Cliente titular; public Cuenta (String codigo, double saldo, Cliente titular){ this.codigo = …; this.saldo = …; this.titular = …; } public String getCodigo (){ return this.codigo; } public double getSaldo (){ // devolvemos el saldo con sólo 2 decimales return Math.round(this.saldo*100.0) / 100.0; } public Cliente getTitular (){ return this.titular; } public void setSaldo (double saldo){ this.saldo = saldo;

} }

Se pide: • crear los archivos Cliente.java y Cuenta.java con el código anterior. • implementar la clase Hipoteca según el diseño de clases UML propuesto. • implementar la clase Banco según el diseño de clases UML propuesto. Deberá controlarse el tamaño de los arrays en los métodos de la clase para evitar errores de memoria.

3. Ejercicio 2: La aplicación cálculo de hipotecas El banco desea generar un listado con las cuotas que un cliente debe pagar por una hipoteca determinada.1 Para ello se debe proporcionar el método generarCuotas(int n), que genera y devuelve un String con una simulación de las n primeras cuotas que se deben pagar de una hipoteca. El banco también desea calcular cuál es la siguiente cuota que un cliente debe pagar para detraerla automáticamente del saldo de la cuenta asociada. Para ello se proporcionará el método amortizar(), al que el banco invocará cuando quiera cobrar la cuota correspondiente al siguiente periodo. El método detraerá del saldo de la cuenta asociada la siguiente cuota y actualizará el importe pendiente a pagar (restándole la cantidad amortizada tx). Si la cuenta no dispusiera de saldo suficiente para cubrir el importe de la siguiente cuota, se imprimiría por pantalla el mensaje de error correspondiente. Las cuotas a pagar por la hipoteca se calculan mediante uno de los siguientes sistemas de amortización, que el cliente decide cuando da de alta la hipoteca: • sistema francés de cuotas constantes • sistema alemán de amortización constante En el sistema francés de amortización las cuotas se pagan mensualmente, y se calculan según las siguientes fórmulas: 1 1 D Cx = tx + Ix tx = R I x = R(1 − ) Rx = n − x +1 n − x +1 (1 + i ) (1 + i ) (1 + i ) n − 1 i (1 + i ) n En el sistema alemán de amortización las cuotas se pagan anualmente, y se calculan según las siguientes fórmulas: D Ix = [D-(x-1)t1]I Rx = t1 + [D-(x-1)t1]I Cx = tx + Ix tx = m Donde:  Cx = cuota a pagar en el periodo x  tx = cantidad a amortizar en el periodo x  Ix= intereses a pagar en el periodo x  Rx = cuota a pagar en el periodo x 1

La hipoteca que presta un banco hay que devolvérsela en cuotas mensuales, añadiendo los intereses que genera el préstamo. Cada cuota Cx que se paga lleva una parte de "devolución" tx de lo prestado (lo que se conoce como amortización y una parte de intereses Ix)

   

D = deuda primaria pendiente de amortizar i = tasa de interés mensual del préstamos = tasa de interés anual / 12 meses n = número de meses que dura el préstamo m = número de años que dura el préstamo

a. Herencia Se propone el diseño de clases de la Figura 2 para modelar la aplicación pedida. Es una modificación del diseño realizado en el enunciado 1, que incorpora la nueva funcionalidad.

Figura 2 Diseño de clases UML

En nuestro caso, cada hipoteca utiliza un sistema de amortización específico para el cálculo de las cuotas, el cual se decide al dar de alta la hipoteca. En esta práctica, el sistema de amortización será siempre el sistema francés. El sistema alemán puede entregarse de forma opcional. Las clases Hipoteca y SistemaAmortizacion tienen establecido una relación de uso. Los métodos amortizar() y generarCuotas(int n) harán uso de esta clase para realizar los cálculos pertinentes. La clase SistemaAmortizacion es una clase genérica (abstracta) que únicamente define los

métodos necesarios para el cálculo de las cuotas e intereses de una hipoteca, pero que no los implementa. Serán las clases que derivan de ella (SistemaAmortizacionFrances y SistemaAmortizacionAleman) quienes implementen cada uno de los algoritmos para el cálculo de hipotecas. Nótese que el nombre de la clase SistemaAmortizacion y sus métodos se han representado en el diagrama de clases UML en itálica: eso significa que la clase y sus métodos son abstractos. Serán las clases derivadas de la clase abstracta quienes implementen esos métodos. En Java la abstracción de clases y métodos se indica mediante el modificador abstract. Así, la implementación de la clase SistemaAmortizacion sería similar a la siguiente (sustituyendo, obviamente, los puntos suspensivos de las definiciones por los parámetros que los métodos deban recibir): abstract class SistemaAmortizacion { public abstract double calcularCuota(...); public abstract double calcularAmortizacion(...); public abstract double calcularInteres(...); } Las clases SistemaAmortizacionFrances y SistemaAmortizacionAleman heredan de la clase abstracta SistemaAmortizacion. Deben implementar el comportamiento de todos los métodos abstractos definidos en la clase padre. class SistemaAmortizacionFrances extends SistemaAmortizacion { public double calcularCuota(...) // ... implementación del método ... public double calcularAmortizacion(...) // ... implementación del método ... public double calcularInteres(...) // ... implementación del método ... } La clase Hipoteca tendrá un atributo de la clase SistemaAmortizacion a cuyos métodos invocará para calcular las distintas cuotas. Al crear una nueva hipoteca se debe indicar el sistema de amortización a utilizar sSistema francés por defecto y alemán de forma opcional). Dependiendo del sistema seleccionado este atributo se instanciará como SistemaAmortizacionAleman ó SistemaAmortizacionFrances. class Hipoteca {

private SistemaAmortizacion sa; public Hipoteca (..., byte sistemaAmortizacion) { if (sistemaAmortizacion==SISTEMA_FRANCES) this.sa = new SistemaAmortizacionFrances(); // Opcional else this.sa = new SistemaAmortizacionAleman(); // ... // ... } Una vez instanciado el sistema de amortización adecuado en el constructor, no será necesario volver a preguntar a qué clase llamar (SistemaAmortizacionAleman o SistemaAmortizacionFrances) en los demás métodos. Si se instanció un objeto sa de la clase SistemaAmortizaciónAleman y realizamos la llamada al método sa.calcularCuota(...), internamente se invocará al método implementado en la clase SistemaAmortizacionAleman; pero si se instanció un objeto de la clase SistemaAmortizacionFrances y se llama al método sa.calcularCuota(...), se invocará entonces al implementado en la clase SistemaAmortizacionFrances. b. Interfaces Una `interface` es similar a una clase, pero en la que sólo podemos definir métodos sin implementación y constantes. No puede contener ni atributos ni cuerpos de métodos. Se utilizan para agrupar comportamientos comunes a diversas clases. La definición de una interface en Java es similar a la de una clase, pero utilizando el término interface en vez de class. Los únicos modificadores que podemos aplicar a una interface son public y abstract, (este último no es necesario ponerlo porque va implícito). Por ejemplo: public interface SistemaAmortizacion { public double calcularCuota(...); public double calcularAmortizacion(...); public double calcularInteres(...); } Para implementar herencia en Java podemos hacer que una clase extienda a otra. Igualmente podemos hacer que una clase implemente varias interfaces (herencia múltiple) mediante el término implements. Por ejemplo: class SistemaAmortizacionFrances implements SistemaAmortizacion {

public double calcularCuota(...) // ... implementación del método ... public double calcularAmortizacion(...) // ... implementación del método ... public double calcularInteres(...) // ... implementación del método ... } Se pide: • implementar la interface SistemaAmortizacion con la definición de los métodos calcularCuota, calcularAmortizacion y calcularInteres, que calcularán cuota, cantidad amortizada e intereses de la hipoteca para un periodo x dado. Los métodos deberán recibir los parámetros necesarios para realizar los cálculos tanto en el sistema de amortización francés como en el alemán. • implementar las clases SistemaAmortizacionFrances y, de forma opcional, SistemaAmortizacionAleman. Ambas deben implementar la interface SistemaAmortizacion y, por tanto, todos sus métodos. • añadir un nuevo atributo de tipo SistemaAmortizacion a la clase Hipoteca. • si se realiza el SistemaAmortizacionAleman, también de forma opcional, se debe modificar el constructor de la clase Hipoteca para que reciba un nuevo parámetro, el sistema de amortización (francés o alemán). Este parámetro podrá ser de tipo byte, de tal modo que si se recibe un 0 estaremos seleccionando el sistema francés y si se recibe un 1 estaremos seleccionando el sistema alemán. El atributo de tipo SistemaAmortizacion se instanciará dependiendo del valor de este parámetro. • implementar los métodos generarCuotas(int n) y amortizar() de la clase Hipoteca, los cuales llamarán a los métodos de la clase SistemaAmortizacion para realizar los cálculos. • añadir al final de la clase Hipoteca un comentario contestando a la siguiente pregunta: si el banco decidiese ofrecer a sus clientes un nuevo sistema de amortización (por ejemplo, el americano) ¿cómo deberíamos modificar nuestro sistema? Enumera qué clases habría que crear y cómo se vería afectada la clase Hipoteca para contemplarlas. Se puede utilizar la clase PruebaBanco para probar la aplicación (incluidas las partes opcionales). /** * Clase PruebaBanco. */ class PruebaBanco { public static void main (String args[]){ Banco banco = new Banco(); //creamos un par de clientes

Cliente cliente1 = new Cliente("31309876-R", "Juan", "Lopez"); Cliente cliente2 = new Cliente("28376749-F", "Maria", "Reyes"); //asignamos los clientes al banco banco.nuevoCliente(cliente1); banco.nuevoCliente(cliente2); //creamos una cuenta para cada cliente Cuenta cuenta1 = new Cuenta("1024-9843-45-8376542567", 10000.0, cliente1); Cuenta cuenta2 = new Cuenta("1024-4978-57-763940586", 10000.0, cliente2); //añadimos las cuentas de los clientes al banco banco.nuevaCuenta(cuenta1); banco.nuevaCuenta(cuenta2); // --- SISTEMA FRANCES ---------------------------------//creamos una hipoteca sobre la cuenta del primer cliente Hipoteca hipoteca1 = new Hipoteca( "1024-9843-45-8376542567", 2.5, 500000.0, 10, cuenta1, SistemaAmortizacion.SISTEMA_FRANCES); //añadimos la hipoteca al banco banco.nuevaHipoteca(hipoteca1); //calculamos las primeras 5 cuotas de la hipoteca System.out.println(hipoteca1.generarCuotas(10)); //pagamos la siguiente cuota del préstamo System.out.println("Saldo de la cuenta "+cuenta1.getCodigo()+" antes de amortizar :"+cuenta1.getSaldo()+" euros"); if (hipoteca1.amortizar()==true) { System.out.println("Saldo de la cuenta "+cuenta1.getCodigo()+" tras amortizar :"+cuenta1.getSaldo()+" euros"); System.out.println("Estado de la hipoteca: "); System.out.println(" Importe pendiente: "+hipoteca1.getImportePendiente()+" euros"); System.out.println(" Cuotas pendientes: "+(hipoteca1.getDuracionAnual()*12-hipoteca1.getNumPeriodosAmortizados())); } else { System.out.println("No se pudo realizar la amortizacion"); } // --- SISTEMA ALEMAN ----------------------------------//creamos una hipoteca sobre la cuenta del segundo cliente Hipoteca hipoteca2 = new Hipoteca( "1024-4978-57-763940586", 15, 500000.0, 8, cuenta2, SistemaAmortizacion.SISTEMA_ALEMAN); //añadimos la hipoteca al banco banco.nuevaHipoteca(hipoteca2); //calculamos las primeras 5 cuotas de la hipoteca

System.out.println(""); System.out.println(hipoteca2.generarCuotas(10)); //pagamos la siguiente cuota del préstamo System.out.println("Saldo de la cuenta "+cuenta2.getCodigo()+" antes de amortizar :"+cuenta2.getSaldo()+" euros"); if (hipoteca2.amortizar()==true) { System.out.println("Saldo de la cuenta "+cuenta2.getCodigo()+" tras amortizar :"+cuenta2.getSaldo()+" euros"); System.out.println("Estado de la hipoteca: "); System.out.println(" Importe pendiente: "+hipoteca2.getImportePendiente()+" euros"); System.out.println(" Cuotas pendientes: "+(hipoteca2.getDuracionAnual()-hipoteca2.getNumPeriodosAmortizados())); } else { System.out.println("No se pudo realizar la amortizacion"); } } }

El resultado de este programa debería ser el siguiente: Simulacion de la hipoteca 1024-9843-45-8376542567 por cuantia de 130000.0 euros con interes fijo del 3.1% y duracion 30 años para el cliente: Lopez, Juan (NIF 31309876-R) Cuota para el periodo 1....555.12 = 219.29 (amortizacion) 335.83 (interes) Cuota para el periodo 2....555.12 = 219.85 (amortizacion) 335.27 (interes) Cuota para el periodo 3....555.12 = 220.42 (amortizacion) 334.7 (interes) Cuota para el periodo 4....555.12 = 220.99 (amortizacion) 334.13 (interes) Cuota para el periodo 5....555.12 = 221.56 (amortizacion) 333.56 (interes) Cuota para el periodo 6....555.12 = 222.13 (amortizacion) 332.99 (interes) Cuota para el periodo 7....555.12 = 222.71 (amortizacion) 332.41 (interes) Cuota para el periodo 8....555.12 = 223.28 (amortizacion) 331.84 (interes) Cuota para el periodo 9....555.12 = 223.86 (amortizacion) 331.26 (interes) Cuota para el periodo 10....555.12 = 224.44 (amortizacion) 330.68 (interes) Saldo de la cuenta 1024-9843-45-8376542567 antes de amortizar :1800.0 euros Saldo de la cuenta 1024-9843-45-8376542567 tras amortizar :1244.88 euros Estado de la hipoteca: Importe pendiente: 129780.71 euros Cuotas pendientes: 359

4. Evaluación La entrega de esta práctica es individual. Para evaluar esta práctica se observarán los siguientes criterios: • • •

Los programas entregados deberán resolver los problemas propuestos en los enunciados. Los archivos Java entregados deberán compilar correctamente. Se indicará en el tag @author el nombre del alumno.

• • • • •

Los programas deberán incluir comentarios y comentarios javadoc. Se deberán seguir las normas de estilo publicadas en la web de la asignatura, en lo referente a nombres de clases, atributos, métodos Se deberá respetar el principio de encapsulamiento. Los diseños realizados deberán estar en concordancia con la orientación a objetos, intentando aprovechar las clases existentes dentro de lo posible. Si la parte opcional funciona correctamente permitirá conseguir 2 punto extra.

5. Normas de entrega Los ficheros Banco.java, Hipoteca.java, SistemaAmortizacion.java, SistemaAmortizacionFrances.java forman la parte básica de la práctica. Si se incluye el fichero SistemaAmortizacionAleman.java, se entenderá que se ha realizado la parte opcional. Todos los ficheros deberán comprimirse en formato ZIP en un fichero con nombre p08-nia.zip (donde nia es el número de identificación de cada alumno), que deberá entregarse a través de Aula Global.

Fechas de entrega: - 27 de Enero de 2006 para los grupos 91 y 92 - 1 de Febrero de 2006 para el grupo 93.

Related Documents

Solemne2
November 2019 4