Implementando Interfaces en Java

Buenas tardes, en esta entrada veremos un poco mas sobre las Interface, viendo como implementarlas adecuadamente.


Cuando implementamos una itnerface, estamos acordando que añadimos el contrato definido en una interface. Esto significa que estamos de acuerdo en proveer una implementación legal para cada método definido en la interface, y cualquiera que sepa lo que parecen hacer los métodos de la interface (No como deben ser implementados) pueden estar seguros de que pueden invocar estos métodos en una instancia de la clase que estemos implementando.

Por ejemplo, si creamos una clase que implementa la interface Runnable (Lo que hace que nuestro código puedaser ejecutado en un hilo específico), debemos proveer el método public void run(). De otra manera, el pobre hilo podría ser enviado a ejecutar nuestro código del objeto Runnable y el hilo entonces descubriría que el objeto no tiene el método run(). Agradecidamente, Java previene esta crisis de ocurrir ejecutando una comprobación del compilador en cualquier clase que reclame la implementación de una interface. Si la clase dice que está implementando una interface, debe tener una implementación para cada método de la interface.

Asumiendo una interface, bounceable, con 2 métodos: bounce(), y setBounceFactor(), la siguiente clase compilará:

public class Ball implements Bounceable{

	public void bounce() {
		
	}

	public void setBounceFactor(int bf) {
		
	}

}

La implementación en clases debe adherir las mismas reglas para las implementación de métodos que las clases que hereden de clases abstractas. En orden de ser implementaciones legales en clases, una implementación de una clase no abstracta debe hacer lo siguiente:

  • Proveer implementaciones concretas para todos los métodos de la interface declarada.
  • Seguir todas las reglas de sustituciones legales.
  • Declarar excepciones no comprobadas en métodos implementados que no sean declarados por el método de la interface, o subclases de aquellas declaradas por el método de la interface.
  • Mantener la firma del método de la interface, y mantener el mismo tipo de retorno (o subtipo).

Pero aún hay mas, una implementación en una clase puede ser por sí misma abstract. Por ejemplo, lo siguiente es un ejemplo legal de una clase Ball implementando la interface Bounceable:

abstract class Ball implements Bounceable{}

¿Vemos que falta algo?. No hemos proveído ningúna implantación de métodos. Y esto esta BIEN. Si la clase que implementa la interface es abstract, puede simplemente pasar la carga a su primera subclase concreta. Por ejemplo, si la clase BeachBall hereda a Ball, y beachBall no es abstract, entonces beachBall proveerá todos los métodos de la interface Bounceable:

class BeachBall extends Ball{

	public void bounce() {
		
	}

	public void setBounceFactor(int bf) {
		
	}

}

Busque clases que pretendan implementar una interface pero que no provean la implementación correcta del método. A menos que la clase que implemente la interface sea abstracta, la clase que implemente la interface debe proveer implementaciones para todos los métodos definidos en la interface.

Hay 2 reglas mas que tenemos que saber y entonces podremos terminar con el tema de las interfaces:

  1. Una clase puede implementar mas de una interface. es perfectamente legal decirlo, por ejemplo, lo siguiente:

    		public class Ball implements Bounceable, Serializable, Runnable { ... }
    		

    Podemos heredar solo una clase, pero implementar varias interfaces. Pero recordemos que las subclases definen quien y que somos, por lo que lo que implementemos define el rol que puede jugar o el gorro que puede llevar, a pesar de como de diferentes podemos ser respecto a otra clase que implemente la misma interface. Por ejemplo, una Persona hereda de SerHumano. Pero una Persona puede implementar como interface Programmer, Snowboarder, Employee, Parent.

  2. Una interface puede por sí misma heredar otra interface, pero nunca implementar nada. El siguiente código es perfectamente legal:

    		public interface Bounceable extends Moveable{ }
    		

    ¿Qué significa esto? La primera clase (no abstracta) que implemente la interface Bounceable debe implementar todos los métodos de Bounceable, además de todos los métodos de Moveable. La subinterface, como podemos llamarla, simplemente añade mas requisitos a la superinterface.

Mantengamonos en esto, porque hay algo extraño. Una interface puede heredar mas de una interface!. Pensemos sobre ello un momento. Sabemos que cuando hablamos de clases, lo siguiente es ilegal:

public class Programmer extends Employee, Geek { } // Ilegal!

Como mencionamos antes, a una clase no se el permite heredar multiples clases en Java. Una interface, sin embargo, es libre de heredar o extender multiples Interfaces.

interface Bounceable extends Moveable, Spherical {
	void bounce();
	void setBounceFactor();
}

interface Moveable{
	void moveIt();
}

interface Spherical{
	void doSphericalThing();
}

En el siguiente ejemplo, Ball requiere implementar Bounceable, mas los métodos de las interfaces que Bounceable hereda (incluyendo cualquier interfaces en aquellas interfaces extendidas, y así hasta que logremos al principio del montón). Por lo que Ball necesitaría parecerse a lo siguiente:

class Ball implements Bounceable{

	public void moveIt() {
		
	}

	public void doSphericalThing() {
		
	}

	public void bounce() {
		
	}

	public void setBounceFactor() {
		
	}
	
}

Si la clase Ball falla al implementar cualquiera de los métodos de Bounceable, Moveable o Spherical, el compilador no dejará que compiles hasta que lo implementes. A no ser, como ya sabemos, que la clase Ball sea marcada como abstract. En ese caso, Ball podría elegir implementar uno, todos, o ninguno de los métodos de cualquiera de las interfaces.

abstract class Ball implements Bounceable{

	public void bounce() {
		
	}

	public void setBounceFactor() {
		
	}
	
}

class SoccerBall extends Ball{

	public void moveIt() {
		
	}

	public void doSphericalThing() {
		
	}
	
}

Esto es todo por hoy respecto a las Interfaces en Java, con lo que hemos podido observar como se implementan y unas reglas al respecto sobre su implementación, que aunque ya hayamso visto anteriormente, aquí se han descrito con bastante mas profundidad.

Sin mas, cualquier aporte o corrección son bienvenidos.

Saludos!!!