POO Interfaces en Java
POO Interfaces en Java
1 de 14 19/4/20 18:59
POO: Interfaces en Java https://aulavirtual.instituto.ort.edu.ar/mod/book...
Tabla de contenidos
1. No a la Herencia Múltiple
3. Un ejemplo
3.1. Combinando interfaces
3.2. Implementación sin fronteras
5. Conclusión
2 de 14 19/4/20 18:59
POO: Interfaces en Java https://aulavirtual.instituto.ort.edu.ar/mod/book...
1. No a la Herencia Múltiple
Como vimos en los textos previos, Java no acepta la Herencia Múltiple entre clases. Es decir, las clases de Java no pueden heredar
directamente de más de una clase (sí indirectamente, a través del árbol de jerarquías).
La razón principal de esta decisión fue que quienes crearon Java, con vasta experiencia en POO usando C++, sabían que la Herencia Múltiple
parece aportar más problemas que los que resuelve, y como quisieron hacer de Java un lenguaje simple, en lo posible sin ambigüedades,
decidieron dejar a la Herencia Múltiple afuera.
No obstante, eran conscientes de que se necesitaba un mecanismo a través del cual las clases pudieran adoptar como propias características
de distintas entidades, aún cuando éstas no estuviesen dentro de la misma línea jerárquica. La opción elegida fue permitir que una clase
pudiese adoptar constantes y �rmas de métodos de variados orígenes, sin importar si su origen pertenece a la misma línea jerárquica (es
decir sin herencia de implementación), siempre y cuando la clase implemente esas �rmas.
3 de 14 19/4/20 18:59
POO: Interfaces en Java https://aulavirtual.instituto.ort.edu.ar/mod/book...
En Java, una interfaz es una especie de plantilla con una o más �rmas (sólo la declaración del método, sin la implementación) y, si fuese
necesario, atributos constantes.
En las interfaces se especi�ca el qué pero no el cómo, permitiendo así extender el contrato funcional de una clase más allá de su propio árbol
de herencia. Serán las clases que implementen estas interfaces las que de�nan el comportamiento de los métodos declarados.
También, al igual que las clases entre sí, una interfaz soporta herencia, pero a diferencia de las clases, las interfaces sí pueden heredar de
más de una interfaz. Y como son tipos de datos válidos, también se pueden declarar variables con su tipo (variables tipo interfaz) y por lo
tanto podrán recibir instancias de objetos que cumplan con la interfaz.
4 de 14 19/4/20 18:59
POO: Interfaces en Java https://aulavirtual.instituto.ort.edu.ar/mod/book...
3. Un ejemplo
Empecemos por el principio. Lo primero que se me ocurre cuando digo incrementable es algo numérico, así que crearemos una clase
Numerador que implemente la interfaz Incrementable. Esta clase sólo tendrá como atributo el número a incrementar (en 1), y su código será
el siguiente:
package interfaces.ejemplo1.entidades;
public Numerador() {
this.numero = 0;
}
public int getNumero() {
return this.numero;
}
@Override
public void incrementar() {
this.numero++;
}
}
Y aquí presentamos el diseño UML de la clase Numerador indicando que implementa Incrementable.
Al igual que sucede con la herencia desde clases abstractas, Numerador está obligada a implementar el método incrementar(), o en su
defecto deberá ser declarada abstracta.
package interfaces;
import interfaces.ejemplo1.entidades.Numerador;
El valor actual es 0
incremento...
El valor actual es 1
5 de 14 19/4/20 18:59
POO: Interfaces en Java https://aulavirtual.instituto.ort.edu.ar/mod/book...
Hasta aquí otra vez nada especial. En de�nitiva, tuvimos que implementar todos los métodos en Numerador. Más allá de que al declarar que
esta clase implementa Incrementable, la estamos obligando a cumplir con el “contrato” que indica que debe tener una implementación del
método incrementar(), no parece que haya nada que no pueda hacerse con los mecanismos que ya conocemos (por ejemplo, hacer que
Numerador herede de una clase abstracta).
Pero supongamos que ahora queremos que los objetos de esta clase sepan mostrarse. Todo indica que alcanza con agregar prolijamente un
“syso” del valor en Numerador dentro de un método que se llame, por ejemplo, mostrar().
OK, perfecto.
Pero se me ocurre que hay muchas cosas que pueden ser mostrables. Una palabra, una foto, un grá�co… ¡tantas cosas! Y me gustaría no
tener que preocuparme por aprender el nombre de cada método que signi�que “mostrar el objeto en cuestión”. El verbo mostrar calza
perfecto, pero no es lo mismo mostrar un número que mostrar un cartel o una imagen.
package interfaces.ejemplo1.entidades;
6 de 14 19/4/20 18:59
POO: Interfaces en Java https://aulavirtual.instituto.ort.edu.ar/mod/book...
Hasta aquí otra vez nada especial. En de�nitiva, tuvimos que implementar todos los métodos en Numerador. Más allá de que al declarar que
esta clase implementa Incrementable la estamos obligando a cumplir con el “contrato” que indica que debe tener una implementación del
método incrementar(), no parece que haya nada que no pueda hacerse con los mecanismos que ya conocemos (por ejemplo, hacer
que Numerador herede de una clase abstracta).
Pero supongamos que ahora queremos que los objetos de esta clase sepan mostrarse. Todo indica que alcanza con agregar prolijamente un
“syso” del valor en Numerador dentro de un método que se llame, por ejemplo, mostrar().
OK, perfecto.
Pero se me ocurre que hay muchas cosas que pueden ser mostrables. Una palabra, una foto, un grá�co… ¡tantas cosas! Y me gustaría no
tener que preocuparme por aprender el nombre de cada método que signi�que “mostrar el objeto en cuestión”. El verbo mostrar calza
perfecto, pero no es lo mismo mostrar un número que mostrar un cartel o una imagen.
package interfaces.ejemplo1.entidades;
package interfaces.ejemplo2.entidades;
import interfaces.ejemplo1.entidades.Incrementable;
7 de 14 19/4/20 18:59
POO: Interfaces en Java https://aulavirtual.instituto.ort.edu.ar/mod/book...
8 de 14 19/4/20 18:59
POO: Interfaces en Java https://aulavirtual.instituto.ort.edu.ar/mod/book...
Para extender el ejemplo, además de declarar a Numerador como mostrable e implementar el método correspondiente, agregaremos dos
clases más: Frase y BarraDeAvance. La primera contendrá un string y será mostrable pero no incrementable, y la última implementará ambas
interfaces, pero en vez de incrementar el valor de un entero agregará caracteres (por ejemplo un asterisco) a un string inicialmente vacío, uno
por cada incremento.
package interfaces.ejemplo3.entidades;
import interfaces.ejemplo1.entidades.Incrementable;
import interfaces.ejemplo2.entidades.Mostrable;
package interfaces.ejemplo3.entidades;
import interfaces.ejemplo2.entidades.Mostrable;
9 de 14 19/4/20 18:59
POO: Interfaces en Java https://aulavirtual.instituto.ort.edu.ar/mod/book...
En el diagrama UML queda bien clara la relación entre las clases y sus interfaces. Salvo en el caso de Frase (que sólo implementa una de las
dos interfaces) las otras dos implementan ambas, cosa que no podrían hacer a través de un árbol jerárquico. Además, BarraDeAvance y
Numerador poco tienen que ver entre sí, salvo que comparten las interfaces Mostrable e Incrementable. Las tres clases declaradas no
forman parte del mismo “linaje”, y sin embargo pueden compartir y cumplir con las mismas interfaces sin impedimento.
El programa que �gura a continuación crea instancias de estas tres clases y muestra algunos detalles de ellas más su contenido. Luego
muestra el resultado de incrementar el valor de los objetos incrementables cinco veces:
package interfaces;
import interfaces.ejemplo1.entidades.Incrementable;
import interfaces.ejemplo2.entidades.Mostrable;
import interfaces.ejemplo2.entidades.Numerador;
import interfaces.ejemplo3.entidades.BarraDeAvance;
import interfaces.ejemplo3.entidades.Frase;
10 de 14 19/4/20 18:59
POO: Interfaces en Java https://aulavirtual.instituto.ort.edu.ar/mod/book...
11 de 14 19/4/20 18:59
POO: Interfaces en Java https://aulavirtual.instituto.ort.edu.ar/mod/book...
Supongamos que queremos llevar cuenta de los gastos que tenemos en una salida. Hay gastos de transporte, compras, otros gastos (la
entrada de un cine, una función de teatro o un recital), gastos en comida, alguna cosa que nos gustó, etc. Lo ideal sería que tener de cada
cosa un comprobante.
Imaginemos una salida a un recital fuera de la ciudad (por ejemplo en La Plata): tengo la entrada al recital, dos boletos de viaje (ida y vuelta),
una comida rápida antes de entrar al recital y una cena tardía. Cada uno de estos eventos fue una compra y tengo el comprobante (bueno…
de la comida rápida no porque fue en un puesto ambulante, pero una nota a mano me alcanza).
Luego de revisar cada tipo de gasto, veo que tanto la Entrada como los Pasajes son Boletos, mientras que los otros comprobantes son una
Factura y una nota que hace de recordatorio del gasto callejero (una CompraSinFactura).
Ahora que el evento ya pasó, solamente me quedan el recuerdo… y los comprobantes. Y para poder aunarlos como tales, creamos la interfaz
Comprobante, por lo que las clases quedan relacionadas así:
Ahora, las cuatro clases que tenemos son también comprobantes. Pero sin embargo, hacia la interfaz van sólo tres �echas que indican
12 de 14 19/4/20 18:59
POO: Interfaces en Java https://aulavirtual.instituto.ort.edu.ar/mod/book...
implementación. La clase Boleto (compartida por Pasaje y Entrada) declara implementar Comprobante porque cada boleto que haya será un
comprobante. No obstante, no implementa el método mostrar(), pues un boleto “ideal” no puede saber qué mostrar. Son sus subclases
quienes implementan el método declarado en la interfaz, y por lo tanto Boleto es una clase abstracta.
Dado que ahora pueden ser identi�cados como comprobantes, podemos guardarlos en una colección y mostrarlos:
package interfaces;
import java.util.ArrayList;
import interfaces.ejemplo4.entidades.CompraSinFactura;
import interfaces.ejemplo4.entidades.Comprobante;
import interfaces.ejemplo4.entidades.Entrada;
import interfaces.ejemplo4.entidades.FechaHora;
import interfaces.ejemplo4.entidades.Pasaje;
import interfaces.ejemplo4.entidades.TicketFactura;
Comprobantes de gastos:
********************************************
Superbanda - Estadio Unico La Plata 22/09/17
Entrada #AAZ1240002136, $1000.00
********************************************
---------------------------------------------------
- T r a n s p o r t e s A U T O P I S T E R O S -
- -
- CABA - La Plata
- Fecha y Hora: [22/09/17 18:30]
- Asiento: 27 ID Pasaje #X2134544
- Importe: $80.00
- -
---------------------------------------------------
CompraSinFactura [fecha=22/09/17, descripcion=Sandwich y Bebida, importe=250.0]
---------------------------------------------------
- T r a n s p o r t e s A U T O P I S T E R O S -
- -
- La Plata - CABA
- Fecha y Hora: [23/09/17 01:00]
- Asiento: 18 ID Pasaje #X2141784
- Importe: $80.00
- -
---------------------------------------------------
******************
Factura 123345
Parrilla Los Nenes
[23/09/17 02:42]
Cena.......$260.00
******************
13 de 14 19/4/20 18:59
POO: Interfaces en Java https://aulavirtual.instituto.ort.edu.ar/mod/book...
5. Conclusión
La declaración de métodos abstractos permite que cada clase tenga su propia implementación de una misma “acción ideal”. Un interfaz lleva
este concepto al extremo. Una interfaz podrá verse como un “molde”, una “declaración de principios”. Dado que no permite
implementaciones (al menos hasta la versión 8 de Java) solamente deja declarar nombres de métodos y adicionalmente atributos de tipos
básicos y declarados como static y �nal (constantes). Así, todos sus métodos deberán ser implementados en otro lugar.
La principal diferencia entre una clase abstracta y una interfaz es que mientras la primera obliga a respetar el esquema de�nido por el árbol
jerárquico de clases, la segunda proporciona un mecanismo de encapsulamiento de los métodos sin forzar el uso de herencia. Esta ventaja
hace que una interfaz puede ser implementada por cualquier número de clases, permitiendo a cada clase compartir la misma interfaz de
programación sin importar qué implementación hagan otras clases de la misma interfaz.
Tanto la “abstracción extrema” como la posibilidad de simular Herencia Múltiple hacen de las interfaces una herramienta importante dentro
del mundo de la POO, posibilitando la construcción de de�niciones sólidas más allá de las implementaciones actuales y futuras.
14 de 14 19/4/20 18:59