Facultad de Ciencias Exactas, Ingeniería y Agrimensura Departamento de Sistemas e Informática Escuela de Electrónica Informática II Práctica Nº 3 - Interfaces Resumen: Esta práctica tiene como objetivo ayudar a comprender e incorporar la utilización de interfaces. Problema 1: (*) a) Defina una interface llamada ExamIntf con los siguientes métodos: get() parámetros: un entero retorno:un double propósito: usa el entero como índice de un array de doubles put() parámetros:un double retorna: un boolean indicando éxito (true) o fracaso (false) propósito: almacena un double. El primer valor debe ser puesto en la posición con índice 0, el siguiente en la posición 1, y así hasta que el array está lleno. Si no hay espacio en el array, retorna false. sort() parámetros: ninguno retorno: ninguno propósito: ordena el array de doubles de menor a mayor. Sólo se ordena la porción del array llena con valores. avg() parámetros: ninguno retorno: un double propósito: hallar el promedio de los valores almacenados en el array y retornar este valor b) Escriba una clase ExamArray que implemente ExamIntf . La clase debe tener un atributo llamado notas que es una referencia a un array de 100 doubles. c) Escriba una clase llamada RecordExamen que use la interface ExamIntf. Deberá: Deberá añadir los valores de la siguiente tabla al objeto de alguna clase que implemente la interface ExamIntf. 12.4 34.2 98.4 87.5 99.34 100.0 75.3 Luego deberá ordenar el array resultante, Imprimir los valores y El promedio 89.6 d) Escriba una clase TestExam con un método main() que cree una instancia de la clase que ha definido en el punto c). Problema 2: 1- Dada la clase abstracta: public abstract class Figura { abstract double area(); } defina las clases Rectangulo, Circulo y Triangulo que extiendan de Figura. Implemente en las clases todos lo métodos y variables necesarios para ello (incluyendo método toString(). Está permitido modificar la clase Figura, siempre que siga siendo abstracta. 2 - Las clases de esta jerarquía deben implementar la interface: public interface Ordenable { boolean menorArea( Figura O1 ); boolean menorPerimetro ( Figura O1); } de manera que sea posible ordenar rectángulos, círculos y triángulos por su área o su perímetro. 3 - Arme una clase Test que tenga un método main que instancie objetos Rectangulo, Circulo y Triangulo, y muestre un mensaje por pantalla indicando cuál el de mayor tamaño mostrando también sus características (ancho, alto, etc.) Nota: Implemente en las clases todos lo métodos y variables necesarios pero siempre al nivel más alto posible de la jerarquía de clases. Problema 3: Se desea desarrollar una aplicación para realizar operaciones aritméticas binarias simples con números reales (Suma, Resta, Multiplicación, División). Se proporcionan una interfaz y la siguiente clase: interface OperacionBinaria { public double opera ( ) ;} class Matematicas{ public static void main ( String [ ] args ) { OperacionBinaria op1 = new Suma ( 4 , 3 ) ; OperacionBinaria op2 = new Resta ( 4 , 3 ) ; OperacionBinaria op3 = new Multiplicacion ( 4 , 3 ) ; OperacionBinaria op4 = new Division ( 4 , 3 ) ; //estas 2 sentencias determinan la relación entre //Multiplicacion/División Suma op5=new Resta(3,4); Suma/Resta Multiplicacion op6=new Division(3,4); OperacionBinaria [] v={op1,op2,op3,op4,op5,op6}; for(int i=0;i<v.length;i++) System.out.println(v[i]); } } Completar con el código de las clases que considere necesarias de forma tal que la clase Matematicas pueda ser compilada y ejecutada sin errores. Problema 4: (*) a) Declare una interface llamada Funcion que tenga un método llamado evaluar() que tome como argumento y retorne un entero. b) Cree una clase Mitad que implemente Funcion y tal que el método evaluar() retorne el valor obtenido de dividir el argumento del método por 2. c) Cree un método que tome como argumento un array de valores enteros y retorne un array de la misma longitud que el primero pero que cada elemento de este nuevo array tenga la mitad del valor del correspondiente elemento en el array pasado como parámetro. En la implementación del método podrá crear una instancia de Mitad y usar dicha instancia para calcular los valores del array a retornar. d) Reescriba el método del punto anterior: el método deberá tener un argumento adicional que sea una referencia de tipo Funcion y deberá usar la misma en lugar de la instancia de tipo Mitad. Problema 5: El API de Java define la interface Comparable como: interface Comparable{ int compareTo(Object O1); } donde x.compareTo(y) retornará –1 si x es menor que y, 0 si son iguales y 1 si x es mayor que y. Defina una clase MyArray que implemente Comparable y cuyos objetos se comporten como arreglos (vectores) de enteros. Objetos de tipo MyArray deben compararse de acuerdo a las sumas de sus elementos. Por ejemplo: int[] a = new int[] {1,2,3,4}; /* crea un array e inicializa los elementos */ int[] b = new int[] {-1,2,-3,4,-5}; MyArray m1 = new MyArray(a); MyArray m2 = new MyArray(b); System.out.println(m1.compareTo(m2)); /* imprime 1, puesto que 1+2+3+4 > -1+2-3+4-5 */ Defina lo suficiente para que la clase MyArray para que el código de más arriba funcione. Problema 6: En un supermercado se han definido las siguientes clases e interface: Producto: define las características básicas de un producto: identificador (idproducto) y precio (precio): public class Producto { private int idproducto; private int precio; public Producto (int id, int p){idproducto=id; precio=p;} public int dameIdProducto () { return idproducto;} public int damePrecio () { return precio;} } Fecha: define una fecha como día, mes y año. public class Fecha { private int dia; private int mes; private int año; public Fecha (int d, int m, int a){ dia=d; mes=m; año=a;} public int dameDia (){ return dia;} public int dameMes (){ return mes;} public int dameAño (){ return año; } } Alimento: productos que son comestibles y tienen además una fecha de caducidad (caducidad) public class Alimento extends Producto { private Fecha caducidad; public Alimento(int id, int p, Fecha c){super(id,p); caducidad =c;} public Fecha dameCaducidad () { return caducidad;} } ProductosEcologicos: define a aquéllos productos que cumplen una norma específica de respeto a la naturaleza y que se caracterizan por disponer de un código de origen que garantiza su carácter de ecológicos public interface ProductoEcologico { public double codigoOrigen (); } a) Codifique la clase Carne como una subclase de Alimento b) Codifique la clase TerneraEcologica como un tipo de carne que es además un productoEcologico c) Escriba una clase con un método main donde cree un almacén como un array de Productos y añada un método boolean hayAlimentosEcologicos(Producto[] Almacen) que devuelve true si en Almacen hay algún Alimento que sea un ProductoEcologico. Problema 7: La mayoría de las aplicaciones gráficas usan colecciones de puntos 2D y 3D ordenados. Un Punto2D es un punto del plano con coordenadas enteras, x e y definidas. En forma análoga un Punto3D es un punto del espacio tridimensional con coordenadas enteras: x, y, z definidas. A veces los puntos tienen asociadas etiquetas que son datos tipo String. Los puntos deben aparecer ordenados en una ventana gráfica. El orden se define de la siguiente forma: de arriba a abajo y de izquierda a derecha. Para el caso de puntos 2D el orden será entonces, por fila (y) y luego por columna (x). Análogamente para el caso de un punto 3D el orden será por fila (y) luego por columna (x) y finalmente por la coordenada de profundidad (z). a) Diseñe e implemente una clase base abstracta llamada Datos represente datos sobre los puntos. Dicha clase debe almacenar una etiqueta asociada a un punto de tipo String que podría estar vacía, deberá tener un constructor con un argumento y un método toString que almacene información sobre la etiqueta. Si necesita algún otro método puede añadirlo. La clase debe implementar la interface Comparable. Queda a criterio del alumno si la clase implementa o no realmente la misma (sí es obligatorio hacerlo para las clases concretas que extiendan de ella). b) Diseñe e implemente una clase concreta Punto2D que extienda de Datos y que almacene información sobre las coordenadas de puntos del plano. La clase deberá tener un constructor que inicialice los campos propios y heredados, un método toString que almacene la información mencionada en el caso del constructor, deberá anular el método para comparar dos Punto2D requerido por la interface Comparable. Puede incluir otros métodos si lo considera necesario. c) Diseñe e implemente una clase concreta Punto3D que extienda de Punto2D y que almacene información sobre las coordenadas de puntos del espacio tridimensional. La clase deberá tener un constructor que inicialice los campos propios y heredados, un método toString que almacene la información mencionada en el caso del constructor, deberá anular el método para comparar dos Punto3D implementando el método requerido por la interface Comparable. El método de comparación debería también servir para comparar objetos de tipo Punto2D con objetos de tipo Punto3D. En este caso, el objeto de tipo Punto2D se deberá considerar como un Punto3D con coordenada z=0. Puede incluir otros métodos si lo considera necesario. d) Diseñe una clase Test con un método main( ) tal que permita: 1.-Crear arrays de objetos que pueden ser de tipo Datos, Punto2D o Punto3D. Deberá escribir código donde se le solicite al usuario ingrese por teclado: la dimensión de los mismos, qué tipo de objeto almacenará en cada posición de los arrays y los datos necesarios para construir cada elemento de un array en particular. 2.-Ordenar los puntos almacenados en un array. 3.-Mostrar por pantalla los puntos ordenados de un array 4.-Poder repetir los 3 puntos anteriores hasta que al solicitar al usuario el ingreso por teclado de la dimensión de un array ingrese una dimensión igual a 0. 5.-La clase Test usa la siguiente clase Sorts que tiene un método static para ordenar arrays de objetos de tipo Comparable: public class Sorts{ public static void sort (Comparable[] objects) { for (int index = 1; index < objects.length; index++){ Comparable key = objects[index]; int position = index; while (position > 0 && objects[position-1].compareTo(key) > 0) { objects[position] = objects[position-1]; position--; } objects[position] = key; } }} Nota: public interface Comparable { public int compareTo(Object o);} El método compareTo debe devolver un entero negativo, 0, o positivo cuando el objeto que recibe el mensaje es menor, igual o mayor que el Object o, pasado como parámetro. Problema 8: Escriba una clase que represente un paquete de información enviado a través de una red. Los paquetes tienen las siguientes características que han sido simplificadas para esta aplicación: a.- La dirección IP del emisor b.- La dirección IP del receptor. Las direcciones IP son números de 12 dígitos c.- Un número identificador (ID) del paquete que puede estar entre 0 y 2.000.000.000 d.- El dato enviado representado por un array de bytes. Para este problema se supone que cada paquete tiene una longitud fija de 1000 bytes. Si la información a enviar ocupa menos espacio se rellena con bytes que van alternando ente valores iguales a -1 y 0. Escriba la clase que represente a uno de estos paquetes. Dicha clase deberá proveer la siguiente funcionalidad. i.- Cree un constructor con parámetros para las direcciones de IP del emisor y receptor, el ID del paquete, y un array de tipo byte. Todos los elementos de este array contienen datos válidos (No datos de relleno). ii.- Implemente un método de acceso para la dirección IP del receptor. iii.- Escriba un método de modificación para especificar un elemento en el array de datos. iv.- Anule el método equals de la clase Object. Dos paquetes se consideran iguales si: las direcciones IP del destinatario y receptor coinciden al igual que los ID de los paquetes comparados. v.- La clase deberá implementar la interface Comparable de java.util . Los paquetes serán ordenados de acuerdo al ID de cada uno. interface Comparable{ int compareTo(Object o);} //Compara este objeto con el especificado. Si this<0 retorna -1, si son iguales retorna 0 y si //this>o retorna 1 Problema 9: Un anillo (representado por la clase Ring) es un par de círculos (representados por la clase Circle) concéntricos especificado por un centro (existe una clase Point para representar cualquier punto del plano) el radio del círculo interior y el ancho del anillo (diferencia entre el radio del círculo exterior y el radio del círculo interior). Dado el siguiente código incompleto de la clase Ring deberá completarla de forma tal que dicha clase implemente Area y Displaceable. El área del anillo es la diferencia entre el área del círculo externo y el área del círculo interno. Para mover un anillo, se deben mover los dos círculos. // completar la declaración de la clase Ring en la forma apropiada public class Ring { private Circle inner, outer; //representan círculos interior y exterior, respectivamente. public Ring(double x, double y, double rad, double width) { //coordenadas x e y del centro, radio del círculo interior y ancho del anillo //completar } // completar } public interface Displaceable { public double getX(); //retorna coordenada x del centro de la figura desplazable public double getY(); //retorna la coordenada y del centro de la figura desplazable public void move(double dx, double dy); //mueve el centro de la figura en dx con respecto al //eje x y dy con respecto al eje y } public interface Area { public double getArea(); } public class Point implements Displaceable { private double x, y; public Point(double x, double y) { this.x = x; this.y = y; } public double getX() { return x; } public double getY() { return y; } public void move(double dx, double dy) { x += dx; y += dy; } } public class Circle implements Displaceable, Area { private Point center; private double radius; public Circle(double x, double y, double radius) { this.center = center; this.radius = radius; center = new Point(x, y); } public double getX() { return center.getX(); } public double getY() { return center.getY(); } public double getRadius() { return radius; } public void move(double dx, double dy) { center.move(dx, dy); } public double getArea() { return Math.PI * radius * radius; } } Solución del problema 1: public interface ExamIntf { public double get(int idx); public boolean put(double val); public void sort(); public double avg(); } public class ExamArray implements ExamIntf { private double[] notas; private int contador; public ExamArray() { notas = new double[100]; for (int i = 0; i < notas.length; i++) notas[0] = 0.0; //OTRA FORMA: contador = 0; java.util.Arrays.fill(notas, 0.0); } public double get(int idx) { return notas[idx]; } public boolean put(double val) { if (contador < notas.length) { notas[contador++] = val; return true; } else return false; } public void sort() { // java.util.Arrays.sort(notas,0,contador); //no valido para J.1.0 double men; for (int i = 0; i < contador - 1; i++) for (int j = i + 1; j < contador; j++) if (notas[i] > notas[j]) { men = notas[j]; notas[j] = notas[i]; notas[i] = men; } } public double avg() { double sum = 0; for (int i = 0; i < contador; i++) sum += notas[i]; return sum / (contador); } } public class RecordExam { public RecordExam(ExamIntf lote) { lote.put(12.4); lote.put(34.2); lote.put(98.4); lote.put(87.5); lote.put(99.34); lote.put(100.0); lote.put(75.3); lote.put(89.6); lote.put(9.6); //lote.put(189.6); lote.sort(); int pos = 0; while (true) { double x = lote.get(pos++); if (x == 0) break; System.out.println(x); } /*otra forma de lo mismo pero desconocemos hasta donde debe llegar i (es mejor la anterior) for (int i=0;i<1000;i++) { double x = lote.get(i) ; if (x==0) break; System.out.println(x); } */ System.out.println("\n" + lote.avg()); } } public class TestExam { public static void main(String[] args) { ExamArray EA1 = new ExamArray(); RecordExam RR = new RecordExam (EA1); } }