Sesi´
on 9. TEMA 11 Clases abstractas. Manejo de
errores y excepciones
Fundamentos de Inform´atica
Jos´e Jaime Noguera Noguera
Contenidos
1 Introducci´on
2 Clases abstractas
3 Errores y excepciones
Temario
Este Tema tiene dos partes. La primera corresponde a clases abs-tractas (apartados 10.3 y 10.4 de la edici´on 5, o 12.3 y 12.4 de la edici´on 6). Las secciones del libro tratan sobre unas clases que se explican en apartados que no entran, con lo cual es complicado se-guir los razonamientos. Lo importante es centrarse en los conceptos clase abstracta y m´etodo abstracto.
La segunda parte del tema hace referencia al manejo de errores y excepciones (tema 12 del libro en la edici´on 5 o tema 14 en la edici´on 6.)
Clase abstracta
Una clase abstracta es una clase de la cual no se van a crear ins-tancias, es decir no tendremos objetos de dicha clase. Su objetivo es ser superclase de otras subclases. Debemos tener en cuenta:
Para declarar una clase como abstracta se debe incluir
abstractantes de class, por ejemplo public abstract class
NombreClase
No se pueden crear instancias de una clase abstracta. Si utilizamosnew NombreClase()nos dar´a un error.
una clase abstracta puede contener m´etodos abstractos (los explicamos despu´es) y tambi´en m´etodos no abstractos (o concretos).
Si una clase contiene m´etodos abstractos necesariamente debe ser abstracta.
M´
etodos abstractos
Se definen como
abstract public/protected TipoRetorno nombreMetodo(lista
de par´ametros);
Caracter´ısticas
Est´an formados ´unicamente por una cabecera de un m´etodo, sin que exista cuerpo. Terminan en punto y coma.
Solo pueden existir dentro de una clase abstracta,
Est´an pensados para que sean sustituidos e implementados en las subclases. Si esto no se hace la subclase deber´a
M´
etodos y clases abstratas
Nota 1
Su nombre proviene de una mala traducci´on al espa˜nol, ya que en ingl´esabstractes resumen y es esto lo que realmente se deber´ıa entender. Las clasesabstractson una clase resumen para sus subclases.
Nota 2
Tanto en la definici´on de clase abstracta como de m´etodo
abstracto el modificador de acceso (public) y la palabra reservada
abstractpueden intercambiarse. El orden mostrado anteriormente
Ejemplo
Retomando el ejemplo de la sesi´on anterior podemos hacer las si-guientes modificaciones para incluir clases y m´etodos abstractos (descargar c´odigo):
Definir Veh´ıculo como clase abstracta, entendiendo as´ı que en el taller s´olo podemos crear objetos de tipo Coches o Motos pero no veh´ıculos; public abstract class Vehiculo
Definir como abstracto el m´etodo mostrarInfo():abstract public void mostrarInfo();
Completar el m´etodo ya implementadomostrarInfo()de las subclases para que imprima la marca y la matr´ıcula.
Diagrama de clases
Observar que BlueJ nos informa de que las clases son abstractas con el identificador«abstract». Adem´as cuando creamos una clase nueva nos permite elegir la opci´on de clase abstracta.
Tratamiento de errores y excepciones
Este tema es bastante confuso ya que al ser muy extenso se dan indicaciones imprecisas del tipo: esto no es una ciencia exacta o esto no lo explicamos porque excede los objetivos de este libro, ... Adem´as la forma de explicarlo difiere seg´un el tutorial o libro que leas. Para aumentar los problemas has de tener en cuenta:
A lo largo del tema aparecen conceptos que no has estudia-do (ya que hemos saltaestudia-do temas y secciones): TreeMap, List, SortedMap, interfaces...
Por tanto, la recomendaci´on es centrarse en entender los conceptos generales que pueden aparecer en el test y no pretender entender todo el tema al detalle.
Objeto cliente y objeto servidor
La nomenclatura de objeto cliente y objeto servidor hace referencia a lo siguiente:
Objeto servidor: es un objeto cualquiera que dispone de m´etodos en el c´odigo de la clase a partir de la cual ha sido instanciado.
Objeto cliente: es un objeto que hace uso de un m´etodo del objeto servidor. Es decir, dentro del objeto cliente se llama a un m´etodo del objeto servidor (mediante notaci´on de punto).
Errores y excepciones
Un error o excepci´on se produce cuando al compilar o ejecutar un programa se llega a una situaci´on en que Java no sabe c´omo actuar. Por ejemplo, se divide por 0, o se intenta abrir un fichero que no exis-te... Ante estas situaciones cabe preguntarse qui´en es el responsable de este error y qui´en debe resolverlo. Imaginemos un objeto clien-te que inclien-tenta ejecutar un m´etodo con un String que en realidad requer´ıa unint:
¿Deber´ıa haberse previsto estas situaciones desde el objeto servidor y haber introducido c´odigo para evitarlo?
(programaci´on defensiva)
¿Deber´ıa el cliente haber evitado el error siendo ”consciente” del tipo de par´ametro necesario?
Errores y excepciones
Hay diversas maneras de tratar estos problemas:
Informar al usuario de que se ha producido un error (¿y si el usuario no es un humano o no entiende lo que se le dice?). Devolver valores booleanos para asegurarnos de que un m´etodo ha realizado su cometido.
Devolver valoresnull en vez de objetos en m´etodos tipo get. Sin embargo estas medidas son normalmente insuficientes y Java dispone de mecanismos m´as eficientes: la generaci´on de objetos es-pec´ıficos que informen del error.
Errores y excepciones
Cuando a un objeto servidor, un cliente le solicita ejecutar uno de sus m´etodos, pero el primero no puede terminar la llamada del segundo, entonces el objeto servidor puede generar un objeto excepci´on:
El objeto excepci´on representa los detalles del fallo de un programa.
El error lo descubre el objeto servidor y genera el objeto excepci´on.
La recuperaci´on del error, en caso de intentarlo, se realiza en el cliente, ya que si el servidor puede por s´ı mismo recuperarse del error, no tiene sentido crear el objeto excepci´on.
El objeto excepci´on es una instancia de una clase de la jerarqu´ıa de clases Throwable.
Jerarqu´ıa de clases
Error: problema grave que no debemos tratar de solucionar:
OutOfMemoryError (memoria agotada), InternalError (error de la JVM)...
Exception: excepciones que podr´ıan evitarse o tratarse. Se
dividen en:
RuntimeException y sus subclases: Excepciones NO COMPROBADAS (unchecked).
El resto de subclases de Exception: excepciones COMPROBADAS (checked).
Excepciones comprobadas y no comprobadas
COMPROBADAS: situaciones en el que el objeto cliente de-ber´ıa esperar que una operaci´on pueda fallar y debe comprobar si ´esta ha tenido ´exito. Deben utilizarse para situaciones que no puede evitar el programador, como problemas de entrada/sa-lida: FileNotFoundException, ZipException, MalformedURLEx-ception ...
NO COMPROBADAS: situaciones en que el objeto cliente nun-ca deber´ıa esperar que fallasen y por tanto no necesita com-probar si las operaciones han tenido ´exito. Corresponden a fa-llos que comete el programador: NullPointerException, ArrayIn-dexOutOfBoundsException, ArithmeticException, NoSuchEle-mentException, ClassCastException...
Lanzando excepciones
Vamos a ver un ejemplo extremadamente sencillo para ilustrar qu´e significa lanzar una excepci´on:
Tenemos una clase Servidor y una clase Cliente. En la clase Servidor hay un m´etodo que si recibe un par´ametro nulo lanza una excepci´on.
Crearemos un objeto tipo Servidor y uno Tipo Cliente. Desde el objeto cliente llamaremos al m´etodo del objeto servidor con par´ametro nulo y se producir´a una excepci´on. A continuaci´on mostramos el c´odigo. Prestar atenci´on a c´omo se lanza una excepci´on:
throw new TipoExcepcion(”Cadena opcional que da informaci´on
Ejemplo: ejecuci´
on
Al ejecutar el Lanzador se lanza una excepci´on (se crea un objeto tipo excepci´on) y el programa finaliza en esa l´ınea de c´odigo. Observar las informaciones que ofrece el terminal y el editor de BlueJ:
Ejemplo: impidiendo crear objetos
En el constructor tambi´en podemos lanzar excepciones, evitando as´ı que se creen objetos con estados iniciales inv´alidos. Por ejemplo modificamos nuestro constructor de la siguiente manera:
Ejemplo: ejecuci´
on
Si ejecutamos el lanzador con la instrucci´on:
Servidor objetoServidor=new Servidor(”casa”);
Ejemplo: excepciones no comprobadas
Las anteriores excepciones son no comprobadas, ya que pueden ser solucionadas modificando el c´odigo, es decir el programador puede evitarlas. Este tipo de excepciones no requieren ninguna compro-baci´on por parte del compilador. La ejecuci´on se detiene y es el programador el que debe solucionar el problema. Otro ejemplo de este tipo de excepciones ser´ıa por ejemplo la que se produce en el siguiente m´etodo que a˜nadimos a nuestra clase Cliente:
Ejemplo: ejecuci´
on
Ejecutamos el Lanzador a˜nadiendo la instrucci´on:
objetoCliente.excepcionNoComprobada();
Observar que es ahora la divisi´on la que lanzar´a una excepci´on tipo
Excepciones comprobadas
Todo lo que veamos ahora para excepciones comprobadas es igual-mente v´alido para excepciones no comprobadas. Sin embargo el tra-tamiento de excepciones solo es obligatorio con las comprobadas, cuyo uso requiere comprobaciones adicionales por parte del compi-lador. En concreto cl´ausulasthrowe instrucciones try. Siguiendo el estilo del libro, no utilizaremosthrow y try en las no comprobadas (aunque puede hacerse).
En parte esto es l´ogico, ya que si la excepci´on es no comprobada, es el programador el que debe mejorar el c´odigo, mientras que si es comprobada es fruto de algo que escapa al control del programador. Las cl´ausulas throw y try le indican a Java qu´e hacer en dichos casos.
Excepciones comprobadas
Tenemos dos opciones para excepciones comprobadas:
Relanzarla mediante la cl´ausula throws: en este caso desde el m´etodo cliente se propaga la excepci´on al m´etodo que ha llamado a este ´ultimo. Si en el m´etodo al que se ha propagado la excepci´on no hay una rutina que la trate se repite el proceso. Si se llega al m´etodo inicial que ha llamado a todos los dem´as y no se trata la excepci´on, la ejecuci´on de detiene
Capturarla mediante las instrucciones try/catch. Es la m´as interesante y la que deber´ıamos utilizar, ya que se evita la in-terrupci´on de la ejecuci´on.
Excepciones comprobadas: relanzarla
El m´etodoleeArchivo()tiene como finalidad leer un archivo llamado
archivo.txt. Si no se encuentra se produce una excepci´on y en este caso se relanza:
Excepciones comprobadas: relanzarla
Si ejecutamos el c´odigo (creando un objeto y ejecutando el m´etodo) obtenemos que la ejecuci´on se para, ya que la excepci´on se relanza. En este caso, dado que el m´etodo que lo ha llamado (main) tampoco tiene una rutina para tratar la excepci´on, entonces se detiene.
Excepciones comprobadas: capturarla
Excepciones Comprobadas: capturarla
En este caso en el bloque try se genera una excepci´on, entonces la ejecuci´on pasa al boque catch. Observar que la ejecuci´onno se
Excepciones Comprobadas: capturarla
El objeto excepci´on que se ha creado, dado que es de tipo IOExcep-tionha sido capturado en la variable e (este es el nombre del objeto, se puede utilizar cualquier nombre). Como todo objeto tendr´a una serie de m´etodos definidos en la claseIOException(o heredados de sus superclases). Los m´as utilizados son:
getMessage(): devuelve un mensage detallado sobre la excepci´on que ha ocurrido.
printStackTrace(): devuelve la traza de la pila de llamadas hasta llegar al error.
Aqu´ıpuedes ver m´as m´etodos o bien en la documentaci´on de la clase
try/catch
try{
se ejecuta primero }
catch(TipoExcepcion nombre){
se ejecuta si hay una excepcion en el bloque try }
finally{
se ejecuta siempre }
Podemos poner uno, varios o ning´un catch (pero debe aparecer finally).
finally es opcional (siempre que est´e el catch). Se pueden anidar varios try/catch/finally
Captura de varias excepciones
try{
se ejecuta primero
}catch(TipoExcepcion1 nombre1){
se ejecuta si hay una excepcion en el bloque try y la excepcion es de tipo TipoExcepcion1
}catch(TipoExcepcion2 nombre2){
se ejecuta si hay una excepcion en el bloque try, la excpecion no es de tipo TipoExcepcion1 pero es de tipo TipoExcepcion2
}
Si TipoExcepci´on1 fuese superclase de TipoExcepci´on2, el segundo catch nunca se ejecutar´ıa ya que la excepci´on se capturar´ıa (en caso de hacerlo) en el primero. Las superclases siempre deben situarse despu´es de sus subclases.
Multicaptura
En Java 7 se permite gestionar m´ultiples excepciones en un solo catch:
try{
se ejecuta primero
}catch(TipoExcepcion1 | TipoExcepcion2 nombre1){
se ejecuta si hay una excepcion en el bloque try y la excepcion es de tipo TipoExcepcion1 o TipoExcepcion2 }
try con recursos
En Java 7 se permite una nueva estructura utilizada principalmente para cerrar archivos autom´aticamente una vez completada la ins-trucci´ontry:
try(FileWriter wrtiter=new FileWriter(filename)){ se ejecuta primero y no es necesario poner una
instruccion writer.close() }catch(IOException e){
se ejecuta si hay una excepcion en el bloque try y la excepcion es de tipo IOException
}
Definici´
on de nuevas clases de excepci´
on
Podemos definir nuestras propias clases de excepci´on, creando sub-clases de la claseException:
public class MiExcepcion extends Exception{ ...
}
A partir de esta subclase podemos lanzar y capturar excepciones
tipoMiExcepcion.
Aparte de los ejemplos del libro, si quieres ver otros (adem´as de ser un buen repaso de todo lo visto):excepciones1,excepciones2
Pregunta
¿Es correcto lo siguiente?
abstract public class Clase(){ ...
Respuesta
¿Es correcto lo siguiente?
abstract public class Clase(){ ...
}
S´ı es correcto. Es el constructor de una clase abstracta. El orden de abstractypublic no importa.
Pregunta
¿Es correcto lo siguiente?
abstract public void metodo(){ ...
Respuesta
¿Es correcto lo siguiente?
abstract public void metodo(){ ...
}
Pregunta
Respuesta
¿Podemos definir un m´etodo abstracto en cualquier clase?
Pregunta
Respuesta
¿Podemos definir un m´etodo no abstracto en una clase abstracta?
Pregunta
Respuesta
¿Podemos definir una clase abstracta sin m´etodos abstractos?
Pregunta
Respuesta
¿Se puede utilizar untry/catch en excepciones no comprobadas?
Pregunta
Si las ´unicas lineas para mostrar algo por pantalla son las que apare-cen aqu´ı y sabiendo que en elbloque de sentencias 1 no se produce ninguna excepci´on, ¿Qu´e se muestra por pantalla?
try{ bloque de sentencias 1 System.out.print("hola"); }catch(TipoExcepcion e){ bloque de sentencias 2 System.out.print("adios"); } System.out.print("fin");
Respuesta
Si las ´unicas lineas para mostrar algo por pantalla son las que apare-cen aqu´ı y sabiendo que en elbloque de sentencias 1 no se produce ninguna excepci´on, ¿Qu´e se muestra por pantalla?
try{ bloque de sentencias 1 System.out.print("hola"); }catch(TipoExcepcion e){ bloque de sentencias 2 System.out.print("adios"); } System.out.print("fin"); Se muestra: holafin
Pregunta
Si las ´unicas lineas para mostrar algo por pantalla son las que apare-cen aqu´ı y sabiendo que en elbloque de sentencias 1 se produce una excepci´on que no es subtipo de TipoExcepcion, ¿Qu´e se muestra por pantalla? try{ bloque de sentencias 1 System.out.print("hola"); }catch(TipoExcepcion e){ bloque de sentencias 2 System.out.print("adios"); } System.out.print("fin");
Respuesta
Si las ´unicas lineas para mostrar algo por pantalla son las que apare-cen aqu´ı y sabiendo que en elbloque de sentencias 1 se produce una excepci´on que no es subtipo de TipoExcepcion, ¿Qu´e se muestra por pantalla? try{ bloque de sentencias 1 System.out.print("hola"); }catch(TipoExcepcion e){ bloque de sentencias 2 System.out.print("adios"); } System.out.print("fin");
Pregunta
Si las ´unicas lineas para mostrar algo por pantalla son las que apa-recen aqu´ı y sabiendo que en elbloque de sentencias 1 se produce una excepci´on que es subtipo de TipoExcepcion, ¿Qu´e se muestra por pantalla? try{ bloque de sentencias 1 System.out.print("hola"); }catch(TipoExcepcion e){ bloque de sentencias 2 System.out.print("adios"); } System.out.print("fin");
Respuesta
Si las ´unicas lineas para mostrar algo por pantalla son las que apa-recen aqu´ı y sabiendo que en elbloque de sentencias 1 se produce una excepci´on que es subtipo de TipoExcepcion, ¿Qu´e se muestra por pantalla? try{ bloque de sentencias 1 System.out.print("hola"); }catch(TipoExcepcion e){ bloque de sentencias 2 System.out.print("adios"); } System.out.print("fin"); Se muestra: adiosfin
Pregunta
Si las ´unicas lineas para mostrar algo por pantalla son las que apa-recen aqu´ı y sabiendo que en elbloque de sentencias 1 se produce una excepci´on que es subtipo de TipoExcepcion, ¿Qu´e se muestra por pantalla? try{ bloque de sentencias 1 System.out.print("hola"); }catch(TipoExcepcion e){ bloque de sentencias 2 System.out.print("adios"); }finally{ System.out.print("buenas"); } System.out.print("fin");
Respuesta
Si las ´unicas lineas para mostrar algo por pantalla son las que apa-recen aqu´ı y sabiendo que en elbloque de sentencias 1 se produce una excepci´on que es subtipo de TipoExcepcion, ¿Qu´e se muestra por pantalla? try{ bloque de sentencias 1 System.out.print("hola"); }catch(TipoExcepcion e){ bloque de sentencias 2 System.out.print("adios"); }finally{ System.out.print("buenas"); } System.out.print("fin"); Se muestra: adiosbuenasfin