PRÁCTICA 2 __________________________________________________________________________________________________________________ Curso 2004-05 Ejercicio 1 (proyecto prCoche) Cread una clase Coche cuyas instancias deben mantener información del nombre de un coche y su precio antes de impuestos. El precio total de un coche se calcula aplicando el IVA al precio marcado; este IVA es el mismo para todos los coches (actualmente es del 16%) aunque puede variar. Dad métodos para cambiar el IVA, calcular el precio total y mostrar el coche como una cadena de caracteres con el formato: <nombre> > <precio_total>. Un coche importado es un coche al que, además del IVA, se le aplica un impuesto de homologa-ción que es específico de cada vehículo y debe darse en el momento de la creación del vehículo. El precio total de un coche importado se calcula como el de cualquier coche, pero ahora hay que sumar el nuevo impuesto. Cread la clase Importado cuyas instancias mantengan información de coches importados. Probad las clases anteriores con la siguiente clase de prueba: public class EjCoches { static public void main(String[] args) { Coche[] cs = { new Coche("Panda", 15000), new Importado("Mercedes", 35000, 5000), new Coche("Toledo", 21000), new Importado("Jaguar", 41000, 6000), new Importado("Porche", 44000, 7000) }; for(Coche c : cs) { System.out.println(c); } // Cambiamos el iva a todos los coches Coche.setPiva(0.18); System.out.println("Con IVA de 18%"); for(Coche c : cs) { System.out.println (c); } } } La salida del programa debe ser: Panda -> 17400.0 Mercedes -> 45600.0 Toledo -> 24360.0 Jaguar -> 53560.0 Porche -> 58040.0 Con IVA de 18% Panda -> 17700.0 Mercedes -> 46300.0 Toledo -> 24780.0 Jaguar -> 54380.0 Porche -> 58920.0 Ejercicio 2 (proyecto prUrna) El objetivo de este ejercicio es crear una clase Urna cuyos objetos puedan contener bolas blancas y negras, y permitan realizar unas ciertas operaciones básicas. En concreto, la clase: • Tendrá un par de variables de instancia, negras y blancas, en las que se almacenará el número de bolas de cada color. • Dispondrá de un constructor que permita crear instancias de la clase con un número inicial de bolas blancas y negras, pasados como parámetros, y deberá garantizar que no se crean urnas con un número negativo de bolas. • E incluirá métodos para: o Consultar el número total de bolas que tiene (totalBolas()); o Extraer una bola aleatoriamente y saber su color (bola()), que vendrá dado por un tipo enumerado, (para extraer una bola aleatoriamente se sumará el número de bolas blancas y negras y se tomará un número aleatorio entre 1 y dicha suma. Si ese número es menor o igual que el número de bolas blancas se supondrá que la bola que sale es blanca; si no, se supondrá que es negra. Utilizad la clase java.util.Random para la generación de números aleatorios. Consultad la ayuda para disponer de información sobre el uso de dicha clase). o Introducir una bola de un color determinado (ponerBlanca() y ponerNegra() ). Programad una aplicación que cree una urna con un cierto número de bolas de cada color y realice con ella el siguiente experimento: • Mientras quede más de una bola en la urna, se sacarán dos bolas. • Si ambas son del mismo color se introducirá una bola blanca en la urna; pero si son de distinto color se introducirá una bola negra (supondremos que se dispone de suficientes bolas de ambos colores fuera de la urna). • Por último, cuando quede sólo una bola, se sacará y se mostrará su color. Repetid la aplicación anterior pero dando el número de bolas blancas y negras iniciales, como parámetros, al ejecutar el programa. Deberá utilizarse el método parseInt(String) de la clase Integer de java.util para convertir un String en un valor del tipo int. Analizad los resultados obtenidos sobre el color de la bola final dependiendo del número de bolas iniciales y de su color. Ejercicio 3 (proyecto prFecha) El actual calendario gregoriano, que se debe al papa Gregorio XIII, se instauró en 1582 y tiene vigencia desde el 15 de Octubre de dicho año. En este calendario se contemplan 97 años bisiestos cada 400 años distribuidos de la siguiente forma: cada año divisible por 400 es bisiesto y, de los demás, también son bisiestos los años divisibles por 4 que no sean seculares (divisibles por 100). En los bisiestos se añade un día más al mes de Febrero. 3.1) Sabiendo esto, impleméntese una clase Fecha cuyos objetos tengan tres variables de estado privadas: día, mes y año con valores enteros correspondientes a los datos de una fecha correcta. Esta clase deberá tener al menos: • Un constructor con tres argumentos de tipo int: día, mes y año, respectivamente, que deberá comprobar si dichos datos corresponden a una fecha correcta antes de aceptarlos; en caso contrario deberá lanzar una excepción del tipo RuntimeException . • Un método público de clase, esBisiesto(int a), para saber si un año a es bisiesto o no (dentro del periodo de vigencia del calendario gregoriano). • Un método público de clase númeroDeDías(int a) que devuelva el número de días de un año y númeroDeDías(int m, int a) que devuelva el número de días del mes m en el año a. • Tres métodos públicos para poder consultar el día, el mes y el año de una fecha. • Un método público para poder calcular los días transcurridos del año hasta la fecha, díasTranscurridosDelAño() y otro para calcular los días que quedan desde la fecha, díasRestantesDelAño() . • Un método público diferenciaDeDíasCon(Fecha f) para calcular la diferencia de días (positiva o negativa) entre la fecha f y la fecha actual. • Métodos para pasar al día siguiente, díaSiguiente(), al día anterior, díaAnterior(), y para trasladar una fecha un número entero (positivo o negativo) de días, trasladar(int ndías). Se deberán redefinir adecuadamente los métodos: equals(Object toString(). obj), hashCode() y La clase Fecha también deberá implementar las interfaces Cloneable, y redefinir el método clone(), y Comparable<Fecha>, para poder comparar fechas, definiendo el método public int compareTo(Object obj), que devolverá -1, 0 ó 1 según que la fecha actual sea anterior, igual o posterior a la fecha referenciada por el objeto obj. 3.2) Defínase una clase DiaDeFecha que extienda la clase anterior incorporando una nueva variable de instancia privada díaSemana, en la que se guardará un número de 0 a 6 indicativo del día de la semana en el que cae la fecha (lunes, martes, ...). Ahora el constructor de DiaDeFecha recibirá como parámetros un día, un mes y un año para formar una fecha y deberá determinar en qué día de la semana cae esa fecha para poder instanciar la variable díaSemana. Para esto se aconseja mantener como constante de clase una fecha correspondiente a un lunes (p.e.: el 24/3/2003). Si los datos de entrada no corresponden a una fecha correcta deberá procederse como en el constructor de la clase Fecha. También se deberá añadir un método de consulta para la nueva variable díaSemana y se deberán redefinir convenientemente los métodos para pasar al día siguiente, al día anterior y para trasladar una fecha un número entero de días; así como los métodos clone() y toString(). 3.3) Prúebense las clases anteriores con un programa que calcule: • El día de la semana en que cae el 19 de Marzo del año 2010. • La fecha correspondiente al primer domingo de Mayo del mismo año. • Cuántos días quedan hasta esta última fecha. • Cuántos días han transcurrido desde el 19 de Marzo de 1625 y qué día de la semana era. • Qué día será dentro de 1000 días. Ejercicio 4 (proyecto prCalendar) Las clases Date, Calendar y TimeZone de java.util se utilizan para la manipulación de fechas. Mientras la clase Date representa fechas en milisegundos, la clase Calendar manipula fechas utilizando unidades más familiares como meses, días, horas y minutos. La clase abstracta Calendar define métodos para realizar aritmética de fechas, e incluye métodos para convertir fechas en el formato de milisegundos utilizado por la clase Date a y desde unidades más comprensibles para los humanos como minutos, horas, días, semanas, meses y años. Como clase abstracta no puede ser directamente instanciada, pero proporciona un método estático getInstance() que devuelve instancias de subclases de Calendar adecuadas para ser utilizadas en una configuración con una zona horaria especificada o por defecto. Calendar define una serie de constantes útiles, unas son valores que representan los días de la semana y los meses del año, otras, como HOUR y DAY_OF_WEEK, representan distintos campos de información de fechas y tiempo. Estas constantes se utilizan para las llamadas a algunos métodos de Calendar como get() y set() para indicar el campo concreto en el que estamos interesados. setTime() y los métodos set() establecen la fecha representada por un objeto Calendar. El método add() añade (o sustrae) valores a un campo de calendario, incrementando el siguiente campo en caso de desbordamiento. La clase GregorianCalendar es una subclase concreta de Calendar que implementa el calendario solar “estándar” con los años numerados desde el nacimiento de Cristo, que es utilizado en la mayoría de configuraciones locales en el mundo. Habitualmente no se utiliza esta clase directamente, sino que se obtiene un objeto de la clase Calendar válida para la configuración local llamando Calendar. getInstance(). La clase Date representa fechas y tiempos, y permite trabajar con ellos de una forma independiente del sistema. Es posible crear una instancia de Date especificando el número de milisegundos desde “the epoch” (media noche GMT del 1 de Enero de 1970). Los años se especifican por el número de años desde 1900. El constructor de Date sin argumentos crea una instancia con la fecha actual. Los métodos de instancia de la clase permiten consultar y cambiar los distintos campos de las fechas, comparar fechas, etc. La clase abstracta TimeZone representa una zona horaria. La forma recomendada de obtener instancias de subclases concretas de ésta es utilizando el método de clase getDefault() de forma que se obtenga la zona temporal indicada en la configuración local; alternativamente se puede usar también el método estático getTimeZone() pasándole como argumento el nombre de la zona deseada. Es posible obtener una lista de los nombres de las zonas con el método estático getAvailableIDs(). Podemos mostrar la fecha actual en España con el siguiente fragmento de código: Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("Europe/Madrid")); Date hoy = cal.getTime(); System.out.println ("Ahora es: " + hoy); Resolved el ejercicio 3 utilizando estas clases de java.lang.