Interfaces

Descargar como pdf o txt
Descargar como pdf o txt
Está en la página 1de 6

Interfaces

Antes de comenzar, vamos a repasar algunos conceptos

Clase abstracta / método abstracto

Una clase abstracta es una clase que no va tener instancias. En Java hay un mecanismo del
lenguaje que permite declarar que una clase sea abstracta, y el compilador garantiza que no va
a existir ninguna instancia.

Tip: La idea es que una clase abstracta tenga descendientes concretos.

Método abstracto: se declara pero no se define, es decir, no tiene código. Esto sirve para
forzar que en las subclases se defina como corresponda.

Tip: La idea es que cualquier clase con algún método abstracto sea abstracta.

¿Para qué sirve que un método sea abstracto?

- ¿Para tener polimorfismo?

Eso se puede conseguir sin tener clases y/o métodos abstractos

La utilidad está en el código que usa las características abstractas, no en las


carácterísticas en sí y en que estoy forzando a todas las subclases a implementar el
método en cuestión

Polimorfismo Y Tipos

En algún momento definimos (informalmente) el polimorfismo como:

la capacidad de que existan métodos distintos con el mismo nombre (en distintas
clases)
Lo más valioso que nos brinda la idea de polimorfismo es que al enviar un mensaje puede
que no sepa, y en principio no me debería importar, qué objeto va a terminar respondiendo
a dicho mensaje.

¿Por qué es valioso?

Porque me permite extender la aplicación y una vez más, el código cliente, es decir, el código
que utiliza los objetos polimórficos no va a verse afectado.

Veamos un ejemplo:

En el siguiente ejemplo, vemos la clase abstracta Animal que define el método abstracto
desplazar y dos clases concretas: Perro y Gato.

Si en un futuro (no muy lejano) necesito agregar otras subclases supongamos Canguro,
Canario, Hamster, nuestro código cliente, en este caso el método Paseador::pasear no se vería
afectado.

Ahora bien....¿Qué ocurre si necesito agregar la clase....Manada?


En este caso, la clase Manada no extiende de la clase Animal pero de todas maneras sería
deseable poder enviarle el mensaje desplazar. El problema es que el código de la clase
Paseador dejaría de funcionar ya que el pasedor puede pasear un animal, pero no una
manada.

En Java, como en todo lenguaje tipado, el tipo de cada objeto debe ser declarado de forma
explícita. Por ahora, el tipo de cada objeto es su clase, y la relación de supertipo/subtipo está
dada por la jerarquía de herencia. Por eso donde declaramos que pasa un Animal podemos
hacer pasar un Perro o un Canguro. Por un lugar donde declaro un parámtro de una
determinada clase, puede pasar una instancia de esa clase, o de cualquier subclase. En el
ejemplo: donde declaro un parámetro de tipo Animal, puede pasar un Perro o un Canguro, pero
no puede pasar una Manada porque no se encuentra en la jerarquía de clases definida.

Interfaces
¿Qué es una interface?

Volvamos al ejemplo anterior, donde aparece la clase Manada. Lo que necesitamos es que el
código en la clase Paseador pueda compilar y funcionar.

Una opción es agregar en la jerarquía de herencia las clases Animal y Manada, haciendo que
alguna sea descendiente de la otra. El problema de esta solución es que además de ser poco
natural, podemos tener el problema que una Manada entiende mensajes que aplicados a un
Animal no tiene sentido (ej. cantidad de integrantes) y viceversa (ej. la edad).

Otra solución sería agregar una superclase que sólo tenga métodos comunes a ambas clases
(Animal y Manada). Supongamos que sólo tienen en común el método desplazar
Con esta solución, el método Paseador::pasear podría recibir un objeto de tipo SerVivo y
funcionaría de forma correcta.

En este caso vemos que la clase SerVivo es puramente abstracta, es decir, sus métodos son
todos abstractos. En lenguajes tipados como Java, existe otra forma de resolver esta situación
a través del concepto de interfaces.

Podemos decir entonces que una interface es un conjunto de declaraciones de métodos,


sin código.

Son tipos, o sea que se pueden declarar variables de tipo interface, y parámetros de tipo
interface, y el tipo de retorno de un método puede ser una interface. Pero no están en la
jerarquía de herencia de clases.

También podemos tener jerarquía de interfaces, aunque no es muy común.

A diferencia de la herencia de clases, donde una clase extiende a otra, con las interfaces se
dice que una clase implementa una interfaz.

Otra diferencia entre el uso de herencia e interfaces, es que en Java no podemos tener
herencia múltiple, es decir, heredar (extender) de varias clases, pero sí podemos implementar
varias interfaces.

¿Cómo me sirven las interfaces?


Supongamos que dentro de nuestro ejemplo queremos incorporar la clase Canario. Claramente
hereda de Animal. Pero también tenemos que implementar el método jugar con la siguiente
restricción: "todos excepto los canarios pueden jugar".

Para resolver este nuevo problema, la solución de una superclase no sería viable, por lo que
vamos a recurrir al uso de interfaces. Nuestro nuevo diagrama de clases quedaria de la
siguiente manera:

Con el diagrama de clases anterior, podemos ver que el método Paseador::pasear funciona
tanto si recibe un animal cualquiera como una manada. Otra ventaja es que no forzamos a la
clase Canario a implementar métodos que no le corresponde.

Resumen: ¿Qué se gana con las interfaces?

Pensando en el método Paseador::pasear ahora puedo pasarle por parámetro cualquier objeto
que implemente la interfaz SerVivo, lo que me permite agregar clases a mi solución a futuro,
siempre y cuando implementen dicha interfaz.

Con esto logramos separar el polimorfismo de la jerarquía de herencia de clases.

Pensemos que sin interfaces, estaríamos forzando a que los objetos que recibe el método
Paseador::pasear debe estar dentro de la jerarquía de Animal, podría ser Gato, Perro pero no
podría ser Manada; lo que nos llevaría al problema inicial.
Con interfaces, elimino dicha limitación. Ahora el método a ser invocado no tiene ninguna
limitación relacionada con la jerarquía de herencia de clases. Alcanza con que el método esté
en una clase que implementa la interface SerVivo, y esas clases pueden estar en cualquier
lado. Las interfaces son tipos y desde este punto de vista lo que estoy logrando es que un
objeto tenga muchos tipos, que en un lenguaje tipado es lo que me permite que lo use en más
contextos.

En resumen, las interfaces permiten explotar más el concepto de polimorfismo.

Pensando más en diseño, al definir una interface estamos definiendo un concepto.

Esta historia continuará cuando veamos patrones...

También podría gustarte