Está en la página 1de 7

31

INTERFACES

Muchas veces se hace necesario establecer métodos y funcionalidades que no dependan de un esquema
específico de implementación establecido en la jerarquía de la herencia. Tomemos como ejemplo las
estructuras de datos. Estas son básicamente colecciones de registros que pueden ser de un tipo de dato
específico o de un tipo de dato abstracto (como un objeto) y que cumplen funcionalidades comunes tales
como poder ingresar datos a la estructura, retirarlos de la estructura o contabilizar la cantidad de elementos
en ella almacenados. No obstante, existen muchas estructuras como las colas, las pilas o las listas, que aunque
tienen estas funcionalidades en común, su algoritmo de implementación interna es bien diferente. Si
quisiéramos utilizar la herencia para crear diferentes estructuras de datos, tendríamos que sobreescribir los
métodos en todas las diferentes estructuras, lo cual haría que la implementación global de todas estas fuera
bastante compleja.

Por ello, Java ofrece el concepto de la Interfaz, la cual no debe confundirse con la Interfaz Gráfica de Usuario
(GUI) de una aplicación. Cuando se habla de interfaz, se hace referencia a una colección de métodos
específicos que no exponen ninguna implementación específica para el programador y de una colección de
valores constantes, pero que si determinan qué parametrización y qué retornos deben establecerse para que
otras clases si se encarguen de realizar la implementación de estas interfaces.
Las interfaces se utilizan para definir un protocolo de comportamiento que puede ser implementado por
cualquier clase del árbol de clases.

Fundamentalmente ellas ofrecen un modelo en el cual se visualizan todos los métodos que una clase debe
implementar, pero sin definir ninguna implementación concreta. Esto permitiría, teóricamente, que una clase
pueda “heredar” de una definición dada por una Interfaz, existiendo múltiples implementaciones de los
métodos, cada una de ellas respondiendo a un conjunto de necesidades específicas de negocio sobre la base
de diferentes problemas de programación.

Por lo tanto, una interface es un conjunto de declaraciones de métodos (sin implementación, es decir, sin
definir el código de dichos métodos). La declaración consta del tipo del valor de retorno y del nombre del
método, seguido por el tipo de los argumentos entre paréntesis. Cuando una clase implementa una
determinada interface, se compromete a dar una definición a todos los métodos de la interface. La ventaja de
las interfaces es que no están sometidas a las reglas de herencia de las clases, por ejemplo una clase no
puede heredar de dos clases pero si puede implementar varias interfaces.

Una interfaz se declara de la siguiente manera:


public interface NombreInterfaz{
//Datos manejados por la interfaz
tipoDato nombreValor;
//Métodos expuestos por la interfaz
visibilidad tipoRetorno nombreMetodo (parámetros) captura
}
Como se observa, no existe una implementación concreta de un método, proceso que si debe realizarse en
aquellas clases destinadas a implementar la interfaz como tal.

A partir del momento en que una interfaz es definida, dado su modificador de acceso público, otras clases
pueden proceder a realizar la implementación de cada método de la interfaz definiendo dentro del cuerpo
algorítmico del método su propio comportamiento para dar respuesta a la lógica de negocio establecida en
los métodos. Para ello, a diferencia de la herencia, la clase que implemente una interfaz no debe usar la
palabra reservada extends, sino la palabra implements, que le indica al compilador que dicha clase será
clase implementadora de la interfaz.
32

El diagrama de clases de la figura indica que las clases


RectanguloGrafico y CirculoGrafico son el resultado tanto
de las clases Rectangulo y Circulo de las que derivan, como
de la interface Dibujable, esta interface está dirigida a
incorporar, en las clases que la implementen, la capacidad
de dibujar sus objetos representándolos gráficamente en la
pantalla

/////////////////////////////////////////////////////////////////////////////

La sentencia public class RectanguloGrafico extends Rectangulo implements Dibujable indica que
RectanguloGrafico deriva de la clase Rectangulo e implementa la interface Dibujable. Se define un nuevo
atributo que se suma a las que ya se tienen por herencia. Esta nueva variable es un objeto de la clase Color.

Hay unas constantes en la clase Color que tienen definidos los valores black , blue, cyan, darkGray, gray,
green, lightgray, magenta, orange, pink, red, white y yellow.

Si estos colores no bastan, podemos crear nuestro propio color a partir de sus valores RGB.

Color c = new Color(r,g,b)


33

Java obliga a implementar o definir siempre todos los métodos declarados por la interface, aunque no se
vayan a utilizar. Esa es la razón de que las sentencias:
public void setPosicion(double x, double y) {

// método vacío pero necesario de definir

definan un método vacío . Como no se va a utilizar no importa que esté vacío, pero Java obliga a dar una
definición o implementación.
34

MANEJO DE LAS EXCEPCIONES


Habitualmente, en programación, se incluyen tantas instrucciones condicionales como sea necesario para
conseguir que una aplicación sea robusta, de esta manera, por ejemplo, en cada división de un valor entre
una variable, antes se comprueba que el denominador no sea cero:

Denominador = ..............
if (Denominador != 0) {
Numerador = ................
Resultado = Numerador / Denominador;
}
else
System.out.println (“No se puede realizar la división”);

Utilizando el mecanismo de excepciones que proporciona Java, en nuestro ejemplo, en lugar de incluir una
serie de instrucciones condicionales para evitar las distintas divisiones entre cero que se puedan dar, se
escribe el programa sin tener en cuenta esta circunstancia y, posteriormente, se escribe el código que habría
que ejecutar si la situación “excepcional” se produce:
35

Una excepción es la indicación de que se produjo un error en el programa. Las excepciones, como su nombre
lo indica, se producen cuando la ejecución de un método no termina correctamente, sino que termina de
manera excepcional como consecuencia de una situación no esperada.

Cuando se produce una situación anormal durante la ejecución de un programa (por ejemplo se accede a un
objeto que no ha sido inicializado o tratamos de acceder a una posición inválida en un vector), si no
manejamos de manera adecuada el error que se produce el programa va a terminar abruptamente su
ejecución. Decimos que el programa deja de funcionar y es muy probable que el usuario que lo estaba
utilizando ni siquiera sepa qué fue lo que pasó.

Cuando durante la ejecución de un método el computador detecta un error, crea un objeto de una clase
especial para representarlo (de la clase Exception en Java), el cual incluye toda la información del problema
tal como el punto del programa donde se produjo, la causa del error, etc. Luego “dispara” o “lanza” dicho
objeto (throw en inglés), con la esperanza de que alguien lo atrape y decida como recuperarse del error. Si
nadie lo atrapa, el programa termina, y en la consola de ejecución aparecerá toda la información contenida
en el objeto que representaba el error. Este objeto se conoce como una excepción.

Los errores de sintaxis son detectados durante la compilación. Pero las excepciones pueden provocar
situaciones irreversibles, su control debe hacerse en tiempo de ejecución y eso presenta un gran problema.

Entendemos por manejar una excepción el hecho de poderla identificar, atraparla antes de que el programa
deje de funcionar y realizar una acción para recuperarse del error (por lo menos, para informarle al usuario
lo sucedido de manera amigable y no con un mensaje poco comprensible del computador).

Tipos de excepciones

Predefinidas en el sistema: Se lanzan automáticamente cuando se realiza alguna operación no valida (acceso
a un objeto que no existe, acceso a una posición de un array que no existe, división por cero)

Generadas por el programador: El programa explícitamente genera una excepción al detectar una situación
de error que no se puede resolver en ese contexto.

La instrucción try-catch

Las sentencias que tratan las excepciones son try y catch. La sintaxis es:
try {
Bloque de Instrucciones
} catch (TipoExcepción nombreVariable) {
Bloque de Instrucciones del primer catch
} catch (TipoExcepción nombreVariable) {
Bloque de Instrucciones del segundo catch
} ...
En la instrucción try-catch hay dos bloques de instrucciones, con los siguientes objetivos:
36

Bloque try: Delimitar la porción de código dentro de un método en el que necesitamos desviar el control si
una excepción ocurre allí. Si se dispara una excepción en alguna de las instrucciones del bloque try, la
ejecución del programa pasa inmediatamente a las instrucciones del bloque catch. Si no se dispara ninguna
excepción en las instrucciones del bloque try, al ejecución continúa después del bloque catch

Bloque catch: Definir el código que manejará el error o atrapará la excepción

El uso de los bloques de sentencias try-catch (Intente y capture) permite al programador controlar
adecuadamente la forma como la aplicación debe comportarse en el momento de dispararse un error, ya sea
porque el usuario ingresó mal los datos o porque se produjo el acceso no deseado o inesperado a un recurso
del código (como por ejemplo el no encontrar un archivo en el disco o no poder leer un valor desde un
dispositivo).

El siguiente ejemplo utiliza el manejo de excepciones para procesar cualquier excepción tipo
ArithmeticException e InputMismatchException que pueda ocurrir. La aplicación pide dos enteros al usuario
y los pasa al método cociente, que calcula el cociente y devuelve un resultado int. Esta aplicación utiliza el
manejo de excepciones de manera que, si el usuario comete un error, el programa atrapa y maneja (es decir,
se encarga de) la excepción; en este caso, le permite al usuario tratar de introducir los datos de entrada otra
vez.
import java.util.InputMismatchException;
import java.util.Scanner;
public class DivisionEntreCeroConManejoDeExcepciones {
public static int cociente(int numerador, int denominador) throws ArithmeticException {
return numerador / denominador;
}
public static void main(String[] args) {
Scanner explorador = new Scanner(System.in);
boolean continuarCiclo = true;
do {
try {
System.out.print("Introduzca un numerador entero: ");
int numerador = explorador.nextInt();
System.out.print("Introduzca un denominador entero: ");
int denominador = explorador.nextInt();
int resultado = cociente(numerador, denominador);
System.out.printf("\nResultado: %d / %d = %d\n",
numerador, denominador, resultado);
continuarCiclo = false;
} catch (InputMismatchException error) {
System.err.printf("\nExcepcion: %s\n", error);
explorador.nextLine();
System.out.println("Debe introducir enteros. Intente de nuevo.\n");
} catch (ArithmeticException error) {
System.err.printf("\nExcepcion: %s\n", error);
System.out.println("Cero es un denominador invalido.
Intente de nuevo.\n");
}
} while (continuarCiclo);
}
}
Cada catch maneja un tipo de excepción. Cuando se produce una excepción, se busca el catch que posea el
manejador de excepción adecuado, será el que utilice el mismo tipo de excepción que se ha producido. Por
lo que si se produjo, por ejemplo, una excepción de tipo AritmethicException y el primer catch captura el
tipo.
37

Algunos ejemplos de excepciones más comunes son:

Clase de Excepción Significado

ArithmeticException Una condición aritmética excepcional ha ocurrido. Por ejemplo,


una división por 0

ArrayIndexOutOfBoundsException Una matriz o array fue accedida con un índice ilegal (fuera de los
límites permitidos)

NullPointerException Se intentó utilizar null donde se requería un objeto

NumberFormatException Se intentó convertir una cadena con un formato inapropiado e un


número

import javax.swing.*;
public class DemoTryCatch {
String mensaje;
public DemoTryCatch() {
String valorCadena=JOptionPane.showInputDialog(null,"Escribe un entero");
try {
int valorNumero=Integer.parseInt(valorCadena);
/*Si lo escrito no es un entero la línea que sigue no se ejecuta,
*el programa busca el bloque catch y ejecuta su contenido
*/
mensaje="Gracias";
}
catch (NumberFormatException ex) {
//El bloque catch indica el error que captura.
mensaje="No escribiste un Entero";
}
JOptionPane.showMessageDialog(null,mensaje);
//El mensaje enviado según el caso
}
public static void main(String[] args) {
new DemoTryCatch();
}
}

USO DE LA CLÁUSULA THROWS


Ahora examinaremos el método cociente. La porción de la declaración del método se conoce como cláusula
throws. Esta cláusula especifica las excepciones que lanza el método. La cláusula aparece después de la lista
de parámetros del método y antes de su cuerpo. Contiene una lista separada por comas de las excepciones
que lanzará el método, en caso de que ocurra un problema. Un método puede lanzar excepciones de las
clases que se listen en su cláusula throws, o en la de sus subclases. Hemos agregado la cláusula throws a esta
aplicación, para indicar al resto del programa que este método puede lanzar una excepción
ArithmeticException.

CUÁNDO UTILIZAR EL MANEJO DE EXCEPCIONES


El manejo de excepciones está diseñado para procesar errores sincrónicos, que ocurren cuando se ejecuta
una instrucción. Ejemplos comunes de estos errores son los índices fuera de rango, el desbordamiento
aritmético (es decir, un valor fuera del rango representable de valores), la división entre cero, los parámetros
inválidos de un método y la asignación fallida de memoria (debido a la falta de ésta).

También podría gustarte