Herencia de interfaces en Java

En el artículo anterior te hablé de la herencia en Java, centrándome en las clases. Ahora vamos a ver cómo funciona la herencia de interfaces en Java, y a qué tienes que prestar atención cuando te enfrentes al examen de certificación de Oracle.

More...

La primera dificultad que puedes encontrar a la hora de implementar una interfaz (recuerda que una clase implementa una o varias interfaces, mientras que una interfaz extiende una o varias interfaces), es que algunas características de los métodos y variables contenidos en las interfaces en Java son implícitas, de manera que, aunque no estén ahí, has de tenerlos en cuenta.

Las variables en las interfaces son siempre public, static y final

Así, tal cual. Recuérdalo, aunque se omitan estas tres palabras clave en la declaración de la variable:

Como ves, aunque la variable de la interfaz no es final de manera explícita, sí lo es de manera implícita. Si ves que el código que se te presente en el examen pretende modificar la variable de una interfaz, ten claro que no va a compilar nunca.

Ya he comentado en este blog alguna vez que en el examen vas a encontrar código que no sigue buenas prácticas. Es decir, te encontrarás con un indentado caótico, nombres genéricos de variables y métodos y nombres de variables repetidos. Unas variables ocultan a otras, y llega un momento en el que no sabes qué variable está siendo modificada. Eso sí: no es lo que tienes que hacer tú en tu código, y es casi seguro que no vas a encontrar un código así fuera del examen. Pero tienes que tenerlo en cuenta.

Puntos a tener en cuenta

  • Recuerda que las variables se ocultan cuando la clase que hereda la interfaz contiene una variable de clase (estática) o de instancia del mismo nombre.

Al igual que en las clases, la variable a la que se accede depende del tipo de referencia que apunte al objeto. Así, la línea 16 modifica la variable declarada en la línea 11. En cambio, la línea 19 intenta modificar la variable declarada en la interfaz. Esta línea no compila, aunque pretenda asignarle el mismo valor que ya posee.

  • Una variable declarada en un método oculta cualquier variable de clase o de instancia del mismo nombre en esa clase.

Al ser la variable declarada en la línea 11 estática, podemos acceder a ella directamente, sin utilizar una instancia de la clase. No obstante, si dentro del método (o en un argumento) se declara una variable del mismo nombre, la variable de instancia o de clase queda oculta. De ahí la diferencia en los resultados.

En este caso, como puedes ver, el problema no estaba relacionado con la variable de la interfaz. Te voy a poner un ejemplo un poco más complicado:

La línea 18 modifica la variable gps declarada en la línea 11. En cambio, al declararse una variable local en la línea 19, la línea 20 modifica esta variable local. En ningún caso se intenta modificar la variable estática de la interfaz, así que el código compila y se ejecuta con normalidad.

Los métodos de las interfaces en Java son siempre public

Esto es muy importante, ya que a la hora de implementar los métodos en la clase, tu método debe ser explícitamente public.

¿Ves la diferencia que hay entre las dos implementaciones? A la derecha, la clase Coche hereda un método abstracto al que pueden acceder otras clases dentro del paquete. La implementación mantiene el mismo acceso (aunque podría ser public). A la izquierda, la clase Coche hereda un método abstracto que, implícitamente, es public. El método implementado ha de ser, entonces, public de manera explícita.

¡Espera! ¿Los métodos de las interfaces en Java son abstractos?

Sí, pueden serlo. Los métodos en las interfaces en Java pueden ser abstractos (abstract), estáticos (static) o predeterminados (default). Lo que tienes que tener en cuenta es que, si son static o default, lo son de manera explícita. En cambio, si son abstract, lo pueden ser de manera implícita.

Si en una interfaz en Java hay un método que no es de manera explícita ni static ni default, entonces es abstract de manera implícita.

Compártelo

Además, los métodos abstract nunca tienen cuerpo, mientras que los static y default sí han de tenerlo en cualquier caso. Recuerda que los métodos default solo pueden aparecer en una interfaz.

Tipo de método

¿Es abstract?

¿Tiene cuerpo?

¿Puede aparecer en una clase?

abstract

Sí, implícito o explícito

Nunca

Sí, en una clase abstracta

static

Nunca

Siempre

Sí, en cualquier clase

default

Nunca

Siempre

No

static y default son mutuamente exclusivos. Si el método es default, no puede ser static, y viceversa.

Los métodos estáticos de las interfaces NO se heredan

Esto es muy importante, ya que los métodos estáticos de las clases sí se heredan, y puede llevar a error. Solo se puede acceder a un método estático de una interfaz mediante una referencia de dicha interfaz.

El método estático de la clase Vehiculo pasa a la clase Coche y un objeto de esta puede ejecutarlo. En cambio, un método estático de la interfaz GPS no es accesible para la clase Coche. Aún siendo el método public, y aunque Coche implemente GPS.

Quizá estés pensando que, al ser un método estático, se oculta y que, para ejecutarlo hay que utilizar una referencia de tipo GPS. Pero no es así:

Solo se puede acceder al método estático de una interfaz citando el nombre de la interfaz. Es por esto que un método estático en una interfaz no puede ser ni abstract ni default: el abstract nunca tiene cuerpo y se implementa en la clase que lo hereda, y el default ofrece un funcionamiento predeterminado. Ambos se crean con la herencia en mente; el método estático, no.

Ejercicios recomendados

Si la clase Coche no hereda el método estático gpsActivado() de la interfaz GPS,

  • ¿puede la clase Coche contener un método estático con el mismo nombre?
  • ¿puede contener la clase Coche un método no estático con el mismo nombre?

Prueba a ejecutar la implementación del método gpsActivado() en la clase Coche utilizando una referencia de tipo GPS y una referencia de tipo Coche.

Deja una respuesta 0 comentarios