INTERFACES
Introducción
Las interfaces Java son expresiones
puras de diseño. Se trata de auténticas conceptualizaciones no implementadas
que sirven de guía para definir un determinado concepto (clase) y lo que debe
hacer, pero sin desarrollar un mecanismo de solución.
Se trata de declarar métodos
abstractos y constantes que posteriormente puedan ser implementados de
diferentes maneras según las necesidades de un programa.
Por ejemplo una misma interfaz podría
ser implementada en una versión de prueba de manera poco óptima, y ser acelerada
convenientemente en la versión definitiva tras conocer más a fondo el problema.
Declaración
Para declarar una interfaz se utiliza
la sentencia interface, de la misma manera que se usa la sentencia class:
interface MiInterfaz {
int CONSTANTE = 100;
int metodoAbstracto( int parametro );
}
Se observa en la declaración que las
variables adoptan la declaración en mayúsculas, pues en realidad actuarán como
constantes final. En ningún caso estas variables actuarán como
variables de instancia.
Por su parte, los métodos tras su
declaración presentan un punto y coma, en lugar de su cuerpo entre llaves. Son
métodos abstractos, por tanto, métodos sin implementación
Implementación de una interfaz
Como ya se ha visto, las interfaces
carecen de funcionalidad por no estar implementados sus métodos, por lo que se
necesita algún mecanismo para dar cuerpo a sus métodos.
La palabra reservada implements utilizada
en la declaración de una clase indica que la clase implementa la interfaz, es
decir, que asume las constantes de la interfaz, y codifica sus métodos:
class ImplementaInterfaz implements
MiInterfaz{
int multiplicando=CONSTANTE;
int metodoAbstracto( int parametro ){
return ( parametro * multiplicando );
}
}
En este ejemplo se observa que han de
codificarse todos los métodos que determina la interfaz (metodoAbstracto()),
y la validez de las constantes (CONSTANTE) que define la interfaz
durante toda la declaración de la clase.
Una interfaz no puede implementar
otra interfaz, aunque sí extenderla (extends) ampliándola.
Herencia múltiple
Java es un lenguaje que incorpora
herencia simple de implementación pero que puede aportar herencia múltiple de
interfaz. Esto posibilita la herencia múltiple en el diseño de los programas
Java.
Una interfaz puede heredar de más de
una interfaz antecesora.
interface InterfazMultiple extends
Interfaz1,Interfaz2{ }
Una clase no puede tener más que una
clase antecesora, pero puede implementar más de una interfaz:
class MiClase extends SuPadre
implements Interfaz1,Interfaz2{ }
Imagen 6: Ejemplo de herencia
múltiple
Para poder llevar a cabo un esquema
como el anterior en Java es necesario que las clases A, B y C de la figura sean
interfaces, y que la clase D sea una clase (que recibe la herencia múltiple):
interface A{ }
interface B extends A{ }
interface C extends A{ }
Colisiones en la herencia múltiple
En una herencia múltiple, los
identificadores de algunos métodos o atributos pueden coincidir en la clase que
hereda, si dos de las interfaces padres tienen algún método o atributo que
coincida en nombre. A esto se le llama colisión.
Esto se dará cuando las clases padre
(en el ejemplo anterior B y C) tienen un atributo
o método que se llame igual. Java resuelve el problema estableciendo una serie
de reglas.
Para la colisión de nombres de
atributos, se obliga a especificar a qué interfaz base pertenecen al
utilizarlos.
Para la colisión de nombres en
métodos:
·
Si tienen el mismo nombre y
diferentes parámetros: se produce sobrecarga de métodos permitiendo que existan
varias maneras de llamar al mismo.
·
Si sólo cambia el valor devuelto: se
da un error de compilación, indicando que no se pueden implementar los dos.
·
Si coinciden en su declaración: se
elimina uno de los dos, con lo que sólo queda uno.
Envolturas de los tipos simples
Los tipos de datos de Java no forman
parte de la jerarquía de objetos. Sin embargo a veces es necesario crear una
representación como objeto de alguno de los tipos de datos simples de Java.
La API de Java contiene un conjunto
de interfaces especiales para modificar el comportamiento de los tipos de datos
simple. A estas interfaces se las conoce comoenvolturas de tipo simple.
Todas ellas son hijas de la clase
abstracta Number y son:
·
Double: Da soporte al tipo double.
·
Float: Da soporte al tipo float.
·
Integer: Da soporte a los tipos int, short y byte.
·
Long: Da soporte al tipo long.
·
Character: Envoltura del tipo char.
·
Boolean: Envoltorio al tipo boolean.
Los métodos abstractos son útiles
cuando se quiere que cada implementación de la clase parezca y funcione igual,
pero necesita que se cree una nueva clase para utilizar los métodos abstractos.
Los interfaces proporcionan un mecanismo para abstraer los métodos a un nivel
superior, lo que permite simular la herencia múltiple de otros lenguajes.
Un interfaz sublima el concepto de
clase abstracta hasta su grado más alto. Un interfaz podrá verse simplemente
como una forma, es como un molde, solamente permite declarar nombres de
métodos, listas de argumentos, tipos de retorno y adicionalmente miembros datos
(los cuales podrán ser únicamente tipos básicos y serán tomados como constantes
en tiempo de compilación, es decir, static y final).
Un interfaz contiene una colección de
métodos que se implementan en otro lugar. Los métodos de una clase son public,
static y final.
La principal diferencia entre interface y abstract es
que un interfaz proporciona un mecanismo de encapsulación de los protocolos de
los métodos sin forzar al usuario a utilizar la herencia. Por ejemplo:
public interface VideoClip {
//
comienza la reproduccion del video
void
play();
//
reproduce el clip en un bucle
void
bucle();
//
detiene la reproduccion
void
stop();
}
Las clases que quieran utilizar el
interfaz VideoClip utilizarán la palabra implements y
proporcionarán el código necesario para implementar los métodos que se han
definido para el interfaz:
class MiClase implements
VideoClip {
void play() {
<código>
}
void bucle() {
<código>
}
void stop() {
<código>
}
Al utilizar implements para el
interface es como si se hiciese una acción decopiar-y-pegar del
código del interface, con lo cual no se hereda nada, solamente se pueden usar
los métodos.
La ventaja principal del uso de
interfaces es que una clase interface puede ser implementada
por cualquier número de clases, permitiendo a cada clase compartir el interfaz
de programación sin tener que ser consciente de la implementación que hagan las
otras clases que implementen el interface.
class MiOtraClase implements
VideoClip {
void play() {
<código nuevo>
}
void
bucle() {
<código nuevo>
}
void
stop() {
<código nuevo>
}
Es decir, el aspecto más importante del
uso de interfaces es que múltiples objetos de clases diferentes pueden ser
tratados como si fuesen de un mismo tipo común, donde este tipo viene indicado
por el nombre del interfaz.
Aunque se puede considerar el nombre
del interfaz como un tipo de prototipo de referencia a objetos, no se pueden
instanciar objetos en sí del tipo interfaz. La definición de un interfaz no
tiene constructor, por lo que no es posible invocar el operador new sobre un
tipo interfaz.
Un interfaz puede heredar de varios
interfaces sin ningún problema. Sin embargo, una clase solamente puede heredar
de una clase base, pero puede implementar varios interfaces. También, el JDK
ofrece la posibilidad de definir un interfaz vacío, como es el caso de Serialize,
que permite serializar un objeto. Un interfaz vacío se puede
utilizar como un flag, un marcador para marcar a una clase con una propiedad
determinada.
La aplicación java514.java,
ilustra algunos de los conceptos referentes a los interfaces. Se definen dos
interfaces, en uno de ellos se definen dos constantes y en el otro se declara
un método put() y un método get(). Las constantes
y los métodos se podrían haber colocado en la misma definición del interfaz,
pero se han separado para mostrar que una clase simple puede implementar dos o
más interfaces utilizando el separador coma (,) en la lista de interfaces.
También se definen dos clases,
implementando cada una de ellas los dos interfaces. Esto significa que cada
clase define el método put() y el métodoget(),
declarados en un interfaz y hace uso de las constantes definidas en el otro
interfaz. Estas clase se encuentran en ficheros separados por exigencias del
compilador, los ficheros son Constantes.java y MiInterfaz.java, y el contenido de ambos ficheros es el que se
muestra a continuación:
public interface Constantes
{
public
final double pi = 6.14;
public
final int constanteInt = 125;
}
public interface MiInterfaz
{
void put( int dato );
int get();
}
Es importante observar que en la
definición de los dos métodos del interfaz, cada clase los define de la forma
más adecuada para esa clase, sin tener en cuenta cómo estará definidos en las
otras clases.
Una de las clases también define el
método show(), que no está declarado en el interfaz. Este método se
utiliza para demostrar que un método que no está declarado en el interfaz no
puede ser accedido utilizando una variable referencia de tipo interfaz.
El método main() en la
clase principal ejecuta una serie de instanciaciones, invocaciones de métodos y
asignaciones destinadas a mostrar las características de los interfaces
descritos anteriormente. Si se ejecuta la aplicación, las sentencias que se van
imprimiendo en pantalla son autoexplicactivas de lo que está sucediendo en el
corazón de la aplicación.
Los interfaces son útiles para recoger
las similitudes entre clase no relacionadas, forzando una relación entre ellas.
También para declarar métodos que forzosamente una o más clases han de
implementar. Y también, para tener acceso a un objeto, para permitir el uso de
un objeto sin revelar su clase, son los llamados objetos anónimos,
que son muy útiles cuando se vende un paquete de clases a otros
desarrolladores.
Hola bro, muy bueno el articulo. Te recomiendo que cambies el color de los primeros párrafos, casi no se ve nada. De resto todo muy bien!
ResponderEliminarOyes puedes cambiar el color de la letra
ResponderEliminarEste comentario ha sido eliminado por el autor.
ResponderEliminar