El concepto de Interface lleva un paso más allá el concepto de una clase abstracta en la que vimos que una clase abstracta es una clase que no se puede instanciar (crear un objeto de esa clase) pero si se pueden definir atributos e implementar métodos
en ella para que sus clases hijas los puedan utilizar. Pues bien una Interface es una clase abstracta pura en la que todos sus métodos son abstractos y por tanto no se pueden implementar en la clase Interface. Se puede pensar, ¿para que vale una
clase abstracta pura en la que no se permiten implementar métodos y que encima en las clases hijas de esa interface tengan que tener "si o si" implementados estos métodos?; pues bien, las Interfaces sirven para establecer la forma que debe de
tener una clase.
Por otro lado se ha de decir que una Interface no se pueden definir atributos, salvo que estos sean estáticos o constantes; es decir, "static" o "final".
Ejemplo de Interfaces:
Veamos un ejemplo en el que simularemos el comportamiento que tendrían los diferentes integrantes de la selección de fútbol; tanto los Futbolistas como el cuerpo técnico (Entrenadores, Masajistas, etc…). Para este ejemplo nos vamos a basar en el siguiente diagrama de clases:

Lo primero que vemos es la clase "IntegranteSeleccionFutbol" que es una Interface en la que tiene definido cuatro métodos (es decir una clase abstracta pura). Como se ha dicho, sólo se definen los métodos pero no se implementan; así que a nivel de código la clase quedaría de la siguiente manera:

Lo siguiente que vemos en el diagrama de clases es la clase "SeleccionFutbol" que es una clase abstracta que utiliza (implements) la Interface "IntegranteSeleccionFutbol". Al ser esta una clase abstracta no se puede instanciar y por tanto en ella no es necesario implementar los métodos de la "Interfece"; pero si será obligatorio implementarlo en sus clases hijas (Futbolista, Entrenador y Masajista).
A continuación vamos a implementar los métodos de la Interface en la clase padre ("SeleccionFutbol") para que solamente haya que implementar los métodos que queramos especializar en las clases hijas. Por tanto la clase "SeleccionFutbol" quedaría de la siguiente forma
package interfaces; public class SeleccionFutbol implements IntegranteSeleccionFutbol{ protected int id; protected String nombre; protected String apellidos; protected int edad; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getNombre() { return nombre; } public void setNombre(String nombre) { this.nombre = nombre; } public String getApellidos() { return apellidos; } public void setApellidos(String apellidos) { this.apellidos = apellidos; } public int getEdad() { return edad; } public void setEdad(int edad) { this.edad = edad; } public SeleccionFutbol(int id, String nombre, String apellidos, int edad) { this.id = id; this.nombre = nombre; this.apellidos = apellidos; this.edad = edad; } //Métodos de la clase public void concentrarse() { System.out.println("Concentrarse (Clase padre)"); } public void viajar() { System.out.println("Viajar (Clase Padre)"); } public void entrenar() { System.out.println("Entrenar (Clase padre)"); } public void jugarPartido() { System.out.println("Asiste al Partido de Fútbol (Clase Padre)"); }
Y en las clases hijas solo implementaremos los métodos de la clase padre que queramos redefinir, quedando las clases hijas de la siguiente forma (recordar que la etiqueta "@Override" significa que ese método esta siendo redefinido)
A nivel de código tendríamos:
Se crea una clase Futbolista, la cual quedaría
package interfaces; public class Futbolista extends SeleccionFutbol{ //Atributos de la clase Futbolista private int dorsal; private String demarcacion; //Getters y Setters public int getDorsal() { return dorsal; } public void setDorsal(int dorsal) { this.dorsal = dorsal; } public String getNumero() { return demarcacion; } public void setNumero(String demarcacion) { this.demarcacion = demarcacion; } //Constructor de la Clase Futbolista public Futbolista(int id, String nombre, String apellidos, int edad, int dorsal, String demarcacion) { super(id, nombre, apellidos, edad); this.dorsal = dorsal; this.demarcacion = demarcacion; } //Métodos propios de la clase Futbolista @Override public void entrenar() { System.out.println("Realiza un entrenamiento (Clase Futbolista)"); } @Override public void jugarPartido() { System.out.println("Juega un Partido (Clase Futbolista)"); } public void entrevista() { System.out.println("Da una Entrevista"); } } }
En la clase Entrenador
package interfaces; public class Entrenador extends SeleccionFutbol{ //Atributos de la clase Entrenador private String idFederacion; //Getters y Setters public String getIdFederacion() { return idFederacion; } public void setIdFederacion(String idFederacion) { this.idFederacion = idFederacion; } //Constructor de la Clase Entrenador public Entrenador(int id, String nombre, String apellidos, int edad, String idFederacion) { super(id, nombre, apellidos, edad); this.idFederacion = idFederacion; } @Override public void entrenar() { System.out.println("Dirige un entrenamiento (Clase Entrenador)"); } @Override public void jugarPartido() { System.out.println("Dirige un Partido (Clase Entrenador)"); } public void planificarEntrenamiento() { System.out.println("Planificar un Entrenamiento"); } }
Y para finalizar la clase Masajista
package interfaces; public class Masajista extends SeleccionFutbol{ //Atributos de la clase Masajista private String titulacion; private int aniosExperiencia; //Getters y Setters public String getTitulacion() { return titulacion; } public void setTitulacion(String titulacion) { this.titulacion = titulacion; } public int getAniosExperiencia() { return aniosExperiencia; } public void setAniosExperiencia(int aniosExperiencia) { this.aniosExperiencia = aniosExperiencia; } //Constructor de la clase Masajista public Masajista(int id, String nombre, String apellidos, int edad, String titulacion, int aniosExperiencia) { super(id, nombre, apellidos, edad); this.titulacion = titulacion; this.aniosExperiencia = aniosExperiencia; } @Override public void entrenar() { System.out.println("Da asistencia en el entrenamiento (Clase Masajista)"); } public void darMasaje() { System.out.println("Da un Masaje"); } }
Llegados a este punto ya tenemos implementada las misma funcionalidad que hicimos en la entrada de Polimorfismo pero diseñada e implementada de otra forma, así que vamos a poner el código que escribimos para esa entrada y observar el resultado
package interfaces; import java.util.ArrayList; public class Main { // ArrayList de objetos SeleccionFutbol. Idenpendientemente de la clase hija a la que pertenezca el objeto public static ArrayList<SeleccionFutbol> integrantes = new ArrayList<SeleccionFutbol>(); public static void main(String[] args) { Entrenador pekerman = new Entrenador(1, "Jose Nestor", "Pekerman", 60, "284EZ89"); Futbolista james = new Futbolista(2, "James", "Rodriguez", 26, 6, "Volante 10"); Masajista raulMartinez = new Masajista(3, "Raúl", "Martinez", 41, "Licenciado en Fisioterapia", 18); integrantes.add(pekerman); integrantes.add(james); integrantes.add(raulMartinez); // CONCENTRACION System.out.println("Todos los integrantes comienzan una concentracion. (Todos ejecutan el mismo método)"); for (SeleccionFutbol integrante : integrantes) { System.out.print(integrante.getNombre() + " " + integrante.getApellidos() + " -> "); integrante.concentrarse(); } // VIAJE System.out.println("\nTodos los integrantes viajan para jugar un partido. (Todos ejecutan el mismo método)"); for (SeleccionFutbol integrante : integrantes) { System.out.print(integrante.getNombre() + " " + integrante.getApellidos() + " -> "); integrante.viajar(); } // ENTRENAMIENTO System.out.println("\nEntrenamiento: Todos los integrantes tienen su función en un entrenamiento (Especialización)"); for (SeleccionFutbol integrante : integrantes) { System.out.print(integrante.getNombre() + " " + integrante.getApellidos() + " -> "); integrante.entrenar(); } // PARTIDO DE FUTBOL System.out.println("\nPartido de Fútbol: Todos los integrantes tienen su función en un partido (Especialización)"); for (SeleccionFutbol integrante : integrantes) { System.out.print(integrante.getNombre() + " " + integrante.getApellidos() + " -> "); integrante.jugarPartido(); } // PLANIFICAR ENTRENAMIENTO System.out.println("\nPlanificar Entrenamiento: Solo el entrenador tiene el método para planificar un entrenamiento:"); System.out.print(pekerman.getNombre() + " " + pekerman.getApellidos() + " -> "); ((Entrenador) pekerman).planificarEntrenamiento(); // ENTREVISTA System.out.println("\nEntrevista: Solo el futbolista tiene el método para dar una entrevista:"); System.out.print(james.getNombre() + " " + james.getApellidos() + " -> "); ((Futbolista) james).entrevista(); // MASAJE System.out.println("\nMasaje: Solo el masajista tiene el método para dar un masaje:"); System.out.print(raulMartinez.getNombre() + " " + raulMartinez.getApellidos() + " -> "); ((Masajista) raulMartinez).darMasaje(); }