Download Interfaces
Document related concepts
no text concepts found
Transcript
Interfaces Amparo López Gaona Septiembre de 2008 Amparo López Gaona () Interfaces Septiembre de 2008 1/1 Interfaces Las interfaces Java permiten al diseñador de clases establecer su forma definiendo el comportamiento que debe tener pero sin especificar la implementarlo. Se trata de declarar métodos abstractos y constantes que posteriormente puedan ser implementados de diferentes maneras. Para crear una interfaz, se utiliza la palabra reservada interface en lugar de class. Para indicar que una clase implementa los métodos de una interfaz se utiliza la palabra clave implements. Amparo López Gaona () Interfaces Septiembre de 2008 2/1 Declaración y uso Ejemplo: interface InstrumentoMusical { void tocar(); void afinar(); String tipoInstrumento(); } Y una clase que implementa la interfaz: class InstrumentoViento implements InstrumentoMusical { void tocar() { . . . }; void afinar() { . . .}; String tipoInstrumento() {} } class FlautaDulce extends InstrumentoViento { String tipoInstrumento() { return "Flauta Dulce"; } Interfaces } Amparo López Gaona () Septiembre de 2008 4/1 Referencias a Interfaces Es posible crear referencias a interfaces. Esta referencia puede ser asignada a objetos de la clase que implementa la interfaz. No se pueden tener objetos de interfaces. InstrumentoMusical instrumento = new FlautaDulce(); instrumento.afinar(); System.out.prinln(instrumento.tipoInstrumento()); InstrumentoMusical instM = new InstrumentoMusical(); //erro Amparo López Gaona () Interfaces Septiembre de 2008 6/1 Agrupaciones de constantes Como todos los datos miembros que se definen en una interfaz son constantes, y las interfaces no pueden instanciarse resultan una buena herramienta para implementar grupos de constantes. Por ejemplo: public interface Meses { int ENERO = 1 , FEBRERO = 2 . . . ; String [] NOMBRES_MESES = { " " , "Enero" , "Febrero" , . . } Esto puede usarse simplemente: System.out.println(Meses.NOMBRES MESES[ENERO]); Amparo López Gaona () Interfaces Septiembre de 2008 8/1 Diferencias entre interfaces y clases abstractas En una interfaz no se implementa ningún método (aunque no se precedan de la palabra abstract). En una clase abstracta puede haber implementaciones. En una interfaz no pueden existir elementos privados. En una clase abstracta puede haber privados, protegidos y públicos. Una interfaz no es parte de la jerarquı́a de clases. Clases sin relación pueden implementarse en la misma interfaz. Una interfaz no tiene constructores. Una clase abstracta puede tener constructores. Una interfaz no puede extender clases. Una clase abstracta puede extender otra clase. Al implementar una interfaz se deben implementar todos los métodos definidos en ella. Al extender una clase abstracta es posible posponer la implementación de métodos. Una clase puede implementar varias interfaces pero sólo puede tener una superclase. Amparo López Gaona () Interfaces Septiembre de 2008 9/1 Elemento mayor de un arreglo Amparo López Gaona () Interfaces Septiembre de 2008 11 / 1 Elemento mayor de un arreglo public class EnteroMayor { private int [] arreglo; EnteroMayor(int [] nums) { arreglo = nums; } public int mayor() { int max = arreglo[0]; for (int i = 1; i < arreglo.length; i++) if (max < arreglo[i]) max = arreglo[i]; return max; } } Amparo López Gaona () Interfaces Septiembre de 2008 11 / 1 ... Elemento mayor de un arreglo 1 Quiero que esta clase sea genérica, ¿cómo hago? Amparo López Gaona () Interfaces Septiembre de 2008 13 / 1 ... Elemento mayor de un arreglo 1 Quiero que esta clase sea genérica, ¿cómo hago? public class EnteroMayor { private Object [] arreglo; EnteroMayor(Object [] nums) { arreglo = nums; } public int mayor() { Object max = arreglo[0]; for (int i = 1; i < arreglo.length; i++) if (max < arreglo[i]) max = arreglo[i]; return max; } } Amparo López Gaona () Interfaces Septiembre de 2008 13 / 1 ... Elemento mayor de un arreglo 1 ¿Cómo comparo? Amparo López Gaona () Interfaces Septiembre de 2008 15 / 1 ... Elemento mayor de un arreglo 1 ¿Cómo comparo? En el paquete java.util existe la interfaz Comparator, definida como sigue: public interface Comparator { public int compare(Object o1, Object o2); public boolean equals(Object obj); } Amparo López Gaona () Interfaces Septiembre de 2008 15 / 1 ... Elemento mayor de un arreglo import java.util.Comparator; public class ObjetoMayor { private Object [] arreglo; private final Comparator prueba; ObjetoMayor(Object [] o, Comparator c) { arreglo = o; prueba = c; } public Object mayor() { Object max = arreglo[0]; for (int i = 1; i < arreglo.length; i++) if (prueba.compare(max,arreglo[i]) < 0) max = arreglo[i]; return max; } } Amparo López Gaona () Interfaces Septiembre de 2008 17 / 1 Implementación del comparador (Envolturas) En lugar de un objeto de una clase puede ir uno de cualquiera de sus subclases. Los tipos primitivos no son clases, por tanto no son subclases de Object, ası́ que no se pueden utilizar en la clase anterior. Java tiene, en el paquete java.lang, clases para trabajar con datos primitivos como objetos. (Envolturas) Boolean, Byte, Double, Float, Integer, Long, Short y Character. Estas clases tienen dos tipos de métodos. Constructores con un parámetro que corresponde a su tipo primitivo. Integer miEntero; int i = 242; miEntero = new Integer(i); Métodos que regresan el valor almacenado dentro de la envoltura. Su nombre es el del tipo primitivo seguido de la palabra Value y no tienen parámetros. i = miEntero.intValue(); Amparo López Gaona () Interfaces Septiembre de 2008 19 / 1 ... Implementación del comparador para enteros public class ComparaEnteros implements java.util.Comparator { public int compare(Object o1, Object o2) { return ((Integer)o1).intValue() - ((Integer)o2).intValue(); } } public class Prueba { public static void main(String [] pps) { Integer [] a = {new Integer(12), new Integer(45), new Integer(67 new Integer(-2), new Integer(-8), new Integer(32 new Integer(125), new Integer(78), new Integer(9 new Integer(670)}; ObjetoMayor objMayor = new ObjetoMayor(a, new ComparaEnteros()); System.out.println("El mayor es "+ (Integer)objMayor.mayor()); } } Amparo López Gaona () Interfaces Septiembre de 2008 21 / 1 ... Implementación del comparador para otros objetos public class ComparaAlumnos implements java.util.Comparator { public int compare(Object o1, Object o2) { if (o1 == o2) return 0; if(o1 == null) return -1; if(o2 == null) return 1; return (int) ((Alumno)o1).promedio() - ((Alumno)o2).promedio(); }} ObjetoMayor objMayor = new ObjetoMayor(a, new ComparaAlumnos()); public class ComparaAlumnos implements java.util.Comparator { public int compare(Object o1, Object o2) { ... // Primeras 3 lineas como antes Estudiante e1 = (Alumno) o1, e2 = (Alumno) o2; int difPromedio = (int) (e2.promedio()-e1.promedio()); if (difPromedio == 0) return e2.obtenNombre().compareTo(e1.obtenNombre()) * (-1); else return difPromedio; } } Amparo López Gaona () Interfaces Septiembre de 2008 23 / 1 Interfaces y TAD public interface Conjuntable { public void agregarElemento(Object elem); public void eliminarElemento(Object elem); public boolean contieneElemento (Object elem); public boolean estaVacio(); public int tamanio(); public Conjuntable union(Conjuntable s1, Conjuntable s2); public Conjuntable interseccion(Conjuntable s1, Conjuntable s2); public Conjuntable diferencia(Conjuntable s1, Conjuntable s2); public boolean subconjunto(Conjuntable s1); } Amparo López Gaona () Interfaces Septiembre de 2008 25 / 1 ... Interfaces y TAD public class Conjunto implements Conjuntable { private Object[] datos; public Conjunto() { this(20); } public Conjunto(int tam) { datos = new Object[tam <= 0 ? 20 : tam]; for (int i = 0; i < datos.length; i++) datos[i] = null; } public boolean estaVacio(){ for (int i = 0; i < datos.length; i++) if (datos[i] != null) return false; return true; } public int tamanio(){ int tam = 0; for (int i = 0; i < datos.length; i++) if (datos[i] != null) tam++; return tam; } public boolean contieneElemento (Object elem){ if (!estaVacio()) for (int i = 0; i < datos.length; i++) if (elem.equals(datos[i])) return true; return false; } Amparo López Gaona () Interfaces Septiembre de 2008 27 / 1 ... Interfaces y TAD public void eliminarElemento(Object elem) { for (int i = 0; i < datos.length; i++) if (elem.equals(datos[i])) { datos[i] = null; return; } throw new ExcepcionDeConjunto("El elemento "+elem+ " no se puede eliminar pues no est\’a en el conjunto"); } public void agregarElemento(Object elem){ if (! contieneElemento(elem)) { for (int i=0; i < datos.length; i++) if (datos[i] == null) { datos[i] = elem; return; } throw new ExcepcionDeConjunto("El conjunto est’a lleno."); } throw new ExcepcionDeConjunto("El elemento "+elem+" ya est’a en el conjunto"); } ... // Otros m’etodos Amparo López Gaona () Interfaces Septiembre de 2008 29 / 1 Iteradores class PruebaConjuntos { public static void main(String [] pps) { Conjunto grupo = new Conjunto(); ... // Instrucciones para llenar el conjunto ?‘C’omo imprimo todos los elementos del conjunto? } } Amparo López Gaona () Interfaces Septiembre de 2008 31 / 1 Iteradores public interface Iterator { public boolean hasNext(); public Object next(); public void remove(); } Los métodos de la interfaz Iterador tienen el siguiente propósito: hasNext devuelve un valor booleano indicando si hay un siguiente elemento (true) y apunta a tal elemento. En caso de no haber más elementos devuelve false. next devuelve el siguiente elemento. Al no haber elemento dispara la excepción NoSuchElementException. remove permite eliminar un elemento de la colección. Amparo López Gaona () Interfaces Septiembre de 2008 33 / 1 ... Iteradores import java.util.*; public class Conjunto implements Conjuntable { ... // Misma estructura y m’etodos que antes public Iterator elementos () { return new miIterador(); } private class miIterador implements Iterator { private int pos; public miIterador(){ pos = 0; } public boolean hasNext() { while (pos < datos.length && datos[pos] == null) pos++; return (pos < datos.length); } public Object next() throws NoSuchElementException { if (hasNext()) return datos[pos++]; throw new NoSuchElementException("No hay elementos en el conjunto"); } public void remove() throws IllegalStateException, NoSuchElementException {} } } Amparo López Gaona () Interfaces Septiembre de 2008 35 / 1 ... Iteradores public static void main( String[] pps) { ... System.out.println("Voy a imprimir: "); for (Iterator it = c.elementos(); it.hasNext();) System.out.print((Integer) it.next() + " "); } Amparo López Gaona () Interfaces Septiembre de 2008 37 / 1 ... Iteradores public static void main( String[] pps) { ... System.out.println("Voy a imprimir: "); for (Iterator it = c.elementos(); it.hasNext();) System.out.print((Integer) it.next() + " "); } Unión de conjuntos Amparo López Gaona () Interfaces Septiembre de 2008 37 / 1 ... Iteradores public static void main( String[] pps) { ... System.out.println("Voy a imprimir: "); for (Iterator it = c.elementos(); it.hasNext();) System.out.print((Integer) it.next() + " "); } Unión de conjuntos public void union(Conjunto c) { Iterator it = c.elementos(); while(it.hasNext()) { agregarElemento(it.next()); } } Amparo López Gaona () Interfaces Septiembre de 2008 37 / 1 Interfaces y polimorfismo En Java sólo existe la herencia simple, pero las clases pueden implementar interfaces. public abstract class Animal { public abstract void hablar(); } class Perro extends Animal{ public void hablar(){ System.out.println("!‘Guau!"); } class Gato extends Animal{ public void hablar(){ System.out.println("!‘Miau!"); } public class AnimalesParlantes { public static void main(String[] pps) { Gato gato=new Gato(); hazleHablar(gato); } static void hazleHablar(Animal sujeto){ sujeto.hablar(); } Amparo López Gaona () Interfaces } } } Septiembre de 2008 39 / 1 ... Interfaces y polimorfismo public interface Parlanchin { public abstract void hablar(); } public abstract class Animal implements Parlanchin{ public abstract void hablar(); } class Perro extends Animal{ public void hablar(){ System.out.println("!‘Guau!"); } } class Gato extends Animal{ public void hablar(){ System.out.println("!‘Miau!"); } Interfaces } Amparo López Gaona () Septiembre de 2008 41 / 1 ... Interfaces y polimorfismo public abstract class Reloj { ... } class Cucu extends Reloj implements Parlanchin{ public void hablar(){ System.out.println("!‘Cucu, cucu, ..!"); } } public class Polimorfismo { public static void main(String[] args) { Gato gato=new Gato(); hazleHablar(gato); Cucu cucu=new Cucu(); hazleHablar(cucu); } static void hazleHablar(Parlanchin sujeto){ sujeto.hablar(); } Amparo López Gaona () Interfaces Septiembre de 2008 43 / 1