Clases abstractas e interfaces Java: Clases Abstractas e Interfaces Franco Guidi Polanco Escuela de Ingeniería Industrial Pontificia Universidad Católica de Valparaíso, Chile fguidi@ucv.cl A nivel conceptual, las clases abstractas e interfaces permiten definir qué puede hacer un conjunto o familia de clases relacionadas. Ejemplo en el contexto de la universidad: Alumno Persona Profesor Administrativo Las personas (esto es, alumnos, profesores y administrativos ) conocen y retornan su RUT, nombre, teléfono y dirección Actualización: 8 de marzo de 2006 2 Clases Abstractas Ejemplo de Clase Abstracta Pablo Picasso, Toro (11) Una clase es declarada abstracta cuando no es posible crear instancias de ella. Una clase debe ser declarada abstracta si posee al menos un método declarado abstracto. Un método abstracto es aquél que no provee implementación. public abstract class Poligono { int lados; public int setlados(int l){ lados = l; public abstract double getarea(); Clase abstracta Polígono Una subclase de una clase abstracta puede ser instanciada (es decir, puede ser no abstracta ) sólo si provee implementación para todos los métodos abstractos de la superclase. En caso contrario, debe también ser declarada abstracta. public class Cuadrado extends Poligono { int longitud; public double getarea(){ return longitud*longitud; Clase concreta que extiende la clase abstracta. 3 4
Interfaces Analogía Una interfaz define un tipo de dato. Contenido de una interfaz: Nombre y visibilidad Eventuales otras interfaces extendidas Declaraciones de métodos Constantes (declaradas como static final) Una interfaz no provee: Variables de instancia o de clase Implementación para los métodos Destornillador Modelos de cabezas De tornillos Clase que debe usar ciertos objetos Interfaces Útiles cuando una clase debe usar objetos de distintas clases, pero que operan de la misma forma (ej. un temporizador para videograbador, radio, etc.) Tornillos Clases que implementan alguna de las interfaces 5 6 Ejemplo de Interfaz Ejemplo de Interfaz (cont.) public interface Despertable { public static final int DORMIDO = 1; public static final int DESPIERTO = 2; public void despierta(); public class Persona implements Despertable{ int estado = DESPIERTO; public void dormir() { estado = Despertable.DORMIDO; public void despierta(){ estado = DESPIERTO; La interfaz Despertable Una clase que implementa la interfaz Despertable public class Alarma { public static void despertar(despertable d); d.despierta(); public class Ejemplo { public static void main(string[] arg){ Persona p1 = new Persona(); Alarma.despertar(p1); Despertable p2 = new Persona(); Alarma.despertar(p2); La Alarma es capaz de despertar cualquier objeto que implemente la interfaz Despertable. 7 8
Uso de Interfaces Una clase puede implementar múltiples interfaces: public class Anfibio implements Terrestre, Acuático { Una interfaz puede extender otras interfaces. Interfaces y excepciones Las excepiones declaradas en los métodos de una interfaz (cláusula throws) también deben ser declaradas en los métodos de las clases que implementan la interfaz. public interface Anfibio extends Terrestre, Acuático { Algunos enuncian que el uso de interfaces representa una forma de enfrentar el problema de la herencia múltiple en Java. 9 10 Ejemplo Ejemplo (cont.) El Aerosub ( Viaje al fondo del mar ) public interface Aéreo { public void despegar(); public void acuatizar(); public interface Acuático { public void emerger(); public void sumergirse(); public class Aerosub implements Aéreo, Acuático{ public void despegar(){ public void acuatizar(){ public void emerger(){ public void sumergirse(){ Clase que accede a las funciones del Aerosub: public class Comandante { public Aerosub vehículo; public Comandante(Aerosub v){ public void comandar(){ vehículo.emerger(); vehículo.despegar(); vehículo.acuatizar(); vehículo.sumergirse(); 11 12
Ejemplo (cont.) Clases que acceden al Aerosub con funcionalidades limitadas: Atención en el uso de la herencia e implementación de Interfaces Deben considerarse relaciones con valor semántico en el dominio del problema. Ejemplos como este pueden no tener sentido: public class Aviador { public Aéreo vehículo; public Aviador(Aéreo v){ public void pilotear(){ vehículo.despegar(); vehículo.acuatizar(); public class Marino { public Acuático vehículo; public Marino(Acuático v){ public void navegar(){ vehículo.sumergirse(); vehículo.emerger(); public class ReyDeLaSelva implements Elefante, Pistola A menos que 13 14 Ejercicio 1 Ejercicio 1 (cont.) Una empresa desarrolladora de software de monitoreo debe crear aplicaciones capaces de obtener datos desde distintos tipos de sensores (de contaminación por partículas, ruido, voltaje, etc.) y mostrar dichos valores por pantalla. Cada aplicación se desarrolla para trabajar con un tipo de sensor. Los sensores son manejados por clases específicas (e.g. TemperatureSensor, DustSensor, etc.) y proveen tres métodos: (1) un método para activarlo; (2) un método que retorna un double correspondiente al valor percibido por el sensor en el momento; y (3) un método para desactivarlo. Los siguientes son ejemplos de aplicaciones desarrolladas por esta empresa: Para manejar un sensor de polvo ambiental public class Muestra { public static void main( String[] arg ){ DustSensor t = new DustSensor(); t.on(); for(int i=0; i<10000; i++ ) System.out.println( t.readmeasure() ); t.off(); Para manejar un sensor de Temperatura public class Muestra { public static void main( String[] arg ){ TempSensor t = new TempSensor(); t.activa(); for(int i=0; i<10000; i++ ) System.out.println( t.leetemp() ); t.desactiva(); A pesar de lo similar de las aplicaciones, en cada ocasión es necesario reescribir no sólo la clase de sensor que se utilizará, sino también las invocaciones correspondientes a sus métodos específicos, lo cual hace el desarrollo ineficiente. Se pide determinar una arquitectura que permita a la empresa simplificar su trabajo de desarrollo. 15 16
Ejercicio 2 La necesidad de clases abstractas e interfaces Diseñe y programe las clases e interfaces que permiten resolver el siguiente problema: Se desea construir una clase que permita mantener una colección de objetos ordenados ascendentemente. Los objetos a ordenar pueden ser de cualquier clase. Los objetos deberán implementar un método que permita determinar si un objeto es mayor que otro. Situación 1: Contexto: se está desarrollando una aplicación que trabaja con CD s, DVD s y discos de vinilo. Problema: se establece que a pesar de tener sus propios atributos, todos ellos disponen de código, sello discográfico y autor. Se desea evitar duplicidad de código. ProductoMusical {abstract código sello autor Decisión: se determina la conveniencia de crear la clase ProductoMusical, que agrupa las propiedades comunes de los tres tipos de productos. La clase ProductoMusical no es instanciable, por lo tanto se lo declara abstracto. CD DVD Vinilo La superclase aparece por factorización de propiedades comunes 17 18 La necesidad de clases abstractas e interfaces (cont.) Discusión Situación 2: Contexto: se está desarrollando una clase Timer para programar distintos objetos temporizables (ej. relojes, grabadoras, alarmas, etc.) Timer La superclase o interfaz es impuesta a las subclases. Tanto clases abstractas como interfaces permiten describir propiedades comunes de familias de clases. Problema: Los objetos temporizables pueden ser distintos, y al momento de desarrollar el Timer no se sabe exactamente de qué clase son. Temporizable {abstract Cuándo conviene utilizar unas u otras? Decisión: se define una interfaz (o una clase abstracta, si hay código en común) que implementarán todos los objetos temporizables. El Timer accede a los objetos temporizables a través de esta interfaz. Reloj Grabadora 19 20