Download Programación Java Curso2006
Document related concepts
no text concepts found
Transcript
Programación Java Curso 2006 - 1 C Polimorfismo Prof.. María Feldgen Ing. Osvaldo Clúa FIUBA Polimorfismo Supongamos una clase Poli con un único método a(): 1. class Poli{ 2. public void a(){System.out.println ("Metodo a() de Poli");} 3. } Ahora dos clases que extienden a Poli 1.class Uno extends Poli{ 2. public void a(){System.out.println ("Metodo a() de Uno");} 3. } 4. 5.class Dos extends Poli{ 6. public void a(){System.out.println ("Metodo a() de Dos");} 7. } y finalmente una clase que quiera utilizar al método a( ) de un Poli 1. class Uso { 2. public void usa(Poli x){x.a();}; 3. } La invocación x.a( ) puede referirse al a( ) de un Poli pero, según el caso, puede referirse además al a( ) de un Uno o de un Dos. En un caso como el que sigue: 1.class Prueba{ 2. public static void main(String arg[]){ 3. Poli p=new Poli(); 4. Uno u= new Uno(); 5. Dos d=new Dos(); 6. Uso s=new Uso(); 7. System.out.print("s.usa(p) "); s.usa(p); 8. System.out.print("s.usa(u) "); s.usa(u); 9. System.out.print("s.usa(d) "); s.usa(d); 10. } 11.} Durante la compilación no hay forma de saber a cual de los métodos a() se refiere la línea 2 de Uso; y en Prueba se ven llamados distintos en 7, 8 y 9 que deberían resultar en invocaciones a distintos a( ). Esta capacidad de decidir en ejecución a qué método llamar se conoce como Polimorfismo. En Java el Polimorfismo está dados sin necesidad de indicarlo expresamente como en C++ o Ada por la propia definición del sistema Lenguaje + Máquina Virtual. Ejercicios: -1- Java 2006 Guía 3 Prof.: Lic. Ing. Osvaldo Clúa Prof. C.C. Maria Feldgen FIUBA/EGRIET. 1) Programe una jerarquía de clases VectorLineal, VectorPlano y VectorEspacial. Cada uno de ellos tiene una componente ortogonal al anterior. Como único método programe toString() que imprima todas las componentes de ese vector (En x si es VectorLineal, en x e y si es VectorLineal y en x, y y z si es VectorEspacial). Programe luego una clase de prueba que genere al azar 2 vectores de cada tipo y los ponga en un arreglo VectorLineal a[ ]. Recorra el arreglo a[..] imprimiendo cada vector. 2) Defina una clase Persona con datos personales y un número de DNI. Defina como subclase Cliente (con numero de Cliente) y como subclases de Cliente a Cliente de Caja de Ahorro (con nro. de Caja y Saldo) y Cliente de Cuenta Corriente (con nro. de cuenta, saldo y acuerdo de giro en descubierto). Para cada una de ellas programe un método toString que pase a String todos los campos . Programe luego una clase que aplique el Polimorfismo como en el problema anterior. 3) Defina una clase Circulo con un campo para guardar su radio y métodos encontrar su superficie y su perímetro, además del consabido toString( ). Extienda por herencia la clase a Elipse con un segundo radio (semieje), especializando lo necesario. Interfaces y clases anónimas. Si se está construyendo un método para obtener el máximo entre dos objetos, posiblemente se use un código como el siguiente: El siguiente código tiene errores: 1. /** Maximo - una clase con un solo metodo que devuelve el 2. maximo entre dos objetos */ 3. 4. class Maximo{ 5. static public Object max (Object uno, Object dos){ 6. if (uno.compareTo(dos) >0) 7. return uno; 8. else return dos; 9. } 10.} y al compilar se obtiene un error: 1. Maximo.java:6: cannot resolve symbol 2. symbol : method compareTo (java.lang.Object) 3. location: class java.lang.Object 4. if (uno.compareTo(dos) >0) que indica que el método compareTo no se encuentra en ningún lado. El hecho que no se haya programado el constructor no es error. Java programará automágicamente un constructor por default sin parámetros. Una solución es crear una jerarquía de clases: 1./** MaxJer Jerarquia de clases para implementar compareTo */ 2. 3.abstract class MaxJer{ 4. abstract int compareTo( MaxJer otro); 5.} 6. 7.class Maximo{ -2- Java 2006 Guía 3 Prof.: Lic. Ing. Osvaldo Clúa Prof. C.C. Maria Feldgen FIUBA/EGRIET. 8. static public Object max (MaxJer uno, MaxJer dos){ 9. if (uno.compareTo(dos) >0) 10. return uno; 11. else return dos; 12. } 13.} y luego hacer descender los objetos que queremos comparar de MaxJer. Cómo el método compareTo(...) no tiene su código, se trata de un método abstract . Una clase con un método abstract no puede instanciarse (usarse para crear objetos), así que también debe ser declarada abstract. Ahora podemos extender MaxJer para alguna clase de la que queramos obtener el máximo, por ejemplo la conocida Racional. 1. /** Racional: como extension de MaxJer */ 2. class Racional extends MaxJer{ 3. private int num=0; 4. private int den=0; 5. Racional(int n,int d) { 6. num=n; den=d;} 7. int getNum() {return num;} 8. int getDen() {return den;} 9. public String toString(){return num+"/"+den;} 10. int compareTo(MaxJer otro){ 11. Racional r= (Racional) otro; 12. return (int) ((double) getNum() / (double) getDen() 13. (double) r.getNum() /(double)r.getDen()); 14. } 15. 16.public static void main(String a[]){ 17. Racional r1= new Racional (1,2); 18. Racional r2= new Racional (3,2); 19. System.out.println ("El maximo entre "+r1+" y "+r2+" es "+ 20. Maximo.max(r1,r2)); 21. } 22.} Observar el manejo de cast y el polimorfismo (si lo puede encontrar). Sin embargo esto trae (al menos) dos problemas: ¿Qué pasa si mi análisis no permite derivar Racional de MaxJer? (Por ejemplo, lo quiere hacer derivar de Numero ) La clase Maximo solo tiene un método, y encima static. ¿No habrá una forma de abreviar todo esto? La respuesta al primer problema es el uso de interface. Una interface es una promesa que, las clases que la implementen programarán ciertos métodos con una signature particular. Además una interface puede usarse en cualquier lugar que se pueda usar una clase. Una clase puede implementar mas de una interface. La respuesta al segundo problema son las clases anónimas. Estas son clases sin nombres que se crean on the fly para poder obtener un objeto sin tanta programación. Se hacen a partir de una clase existente o de una interface para que los métodos creados sean visibles. 1. /** Maxi, resolucion del maximo usando interfaces */ 2. -3- Java 2006 Guía 3 Prof.: Lic. Ing. Osvaldo Clúa Prof. C.C. Maria Feldgen FIUBA/EGRIET. 3. 4. 5. 6. 7. 8. 9. interface Comparable{ int compareTo (Object otro); } interface Maximo { Object max( Comparable uno, Comparable dos); } /** Racional no extiende a nadie, pero podria venir de otra jerarquia como por ejemplo Numero */ 10. 11.class Racional implements Comparable{ 12. private int num=0; 13. private int den=0; 14. Racional(int n,int d) { 15. num=n; den=d;} 16. int getNum() {return num;} 17. int getDen() {return den;} 18. public String toString(){return num+"/"+den;} 19. public int compareTo(Object otro){ 20. Racional r= (Racional) otro; 21. return (int) ((double) getNum() / (double) getDen() 22. (double) r.getNum() /(double)r.getDen()); 23. } 24. 25. public static void main(String a[]){ 26. Racional r1= new Racional (1,2); 27. Racional r2= new Racional (3,2); 28. Maximo maxi=new Maximo(){ 29. public Object max (Comparable uno, Comparable dos){ 30. if (uno.compareTo(dos) >0) 31. return uno; 32. else return dos;} 33. }; 34. System.out.println ("El maximo entre "+r1+" y "+r2+" es "+ 35. maxi.max(r1,r2)); 36. } 37.} El objeto maxi creado a partir de la interface Maximo en la línea 29 hace uso de la facilidad de clase anónima. En alguno de los ejercicios las ventajas serán más evidentes. La interface Comparable existe y forma parte de java.lang . 1) Defina la interface Comparable como en java.lang y prográmela para los vectores (compare módulos), las personas (compare DNI) y los óvalos (Compare superficies). 2) Luego defina una clase de utilidades para Comparables con métodos (estáticos) para: 2.1) Encontrar el máximo. 2.2) Encontrar el mínimo. Aplique estos métodos a vectores, personas y óvalos. -4-