Por 9.99€ al mes tendrás acceso completo a todos los cursos. Sin matrícula ni permanencia.
Una interface es un contrato, una forma de asegurarse que todo el mundo que la implemente va a hacer algo. No nos importa como vayan a hacerlo pero estamos seguros que si una clase implementa una interface entonces va a tener que cumplir el contrato e implementar lo acordado.
En Java, una interface es un tipo de referencia, similar a una clase, cuyo cuerpo puede contener:
- Default methods (métodos con cuerpo).
- Métodos estáticos (también pueden tener cuerpo)
- Métodos abstractos.
- Constantes.
Todos los métodos de una interfaz son públicos.
Una clase que implemente una interface también deberá implementar todos sus métodos.
Una variable estática definida dentro de una interfaz será implícitamente definida como constante.
Todos los métodos abstractos, estáticos y default de una interfaz son implícitamente public. Por tanto, es posible omitir este modificador.
Una interfaz está pensada para ser sobrescrita, luego no tiene sentido utilizar modificadores privados dentro de una interfaz y no están permitidos.
interface Instrument{
void play();//automáticamente público
}
public class Clase implements Instrument{
public static void main(String[] args) {
Clase c = new Clase();
c.play();
}
public void play() {
System.out.println("Jugar al baloncesto");
}
}
Una interfaz puede parecer similar a una clase abstracta, pero tiene varias diferencias:
- Todos los métodos de una interfaz se declaran implícitamente como abstractos y públicos.
- Una interfaz no puede implementar ningún método (ya que todos son abstractos).
- Una interfaz no declara variables de instancia.
- Una clase puede implementar varias interfaces.
Ejemplo de uso
En el siguiente ejemplo, tenemos dependencias de la clase TraductorMaster y TranslateAll. La clase Conector equivaldría a nuestro inyector de dependencias (si lo estuviesemos usando) y se encarga de suministrar una dependencia a la interfaz. Las dependencias TraductorMaster y TranslateAll son intercambiables entre sí, ya que ambas implementan la misma interfaz y por tanto cumplen el mismo contrato.
public interface ITranslate {
void translate(String txt);
}
public class Main1 {
public static void main(String[] args) {
// El inyector de dependencias se encargaría de pasarle el TraductorMaster a la interfaz
ITranslate implementacionEscogida = new TraductorMaster();
Conector conector = new Conector(implementacionEscogida);
conector.traducir("Hola");
}
}
public class Main2 {
public static void main(String[] args) {
// El inyector de dependencias se encargaría de pasarle el TraductorMaster a la interfaz
ITranslate implementacionEscogida = new TraductorMaster();
Conector conector = new Conector(implementacionEscogida);
conector.traducir("Hola");
}
}
public class Conector {
private ITranslate traductor;
public Conector(ITranslate implementacionTraductor) {
this.traductor = implementacionTraductor;
}
// En un caso real, con inyector de dependencias, el método traducir no sería necesario,
// podríamos llamar directamente al método translate a partir de la interfaz
public void traducir(String texto){
this.traductor.translate(texto);
}
}
public class TraductorMaster implements ITranslate{
@Override
public void translate(String txt) {
System.out.println(txt + " traducido");
}
}
public class TranslateAll implements ITranslate {
public void translate(String txt) {
System.out.println(txt +"traducido");
}
}
Ejercicio – animales con interfaz
Implemente las clases del siguiente diagrama.
Desarrolle una clase con el nombre Main, que contenga un método public static void main(String args[]), que al ejecutarse genere una instancia de Vaca, Cerdo y Gallina pasándoles en el constructor el sonido que deben emitir («muuuuuu«, «oinkoink«, «kokoroko», por ejemplo). Sobreescribir el método comunicarse de cada clase para que cada una muestre un mensaje distinto. Puede ser algo del tipo…
System.out.println("Cuando la vaca tiene leche hace " + sonido);
Instanciar además un objeto de la clase Granjero que también implementará la interfaz comunicable.
Llamar a los métodos comunicarse() de cada una de las tres instancias.