Saltar al contenido principal
Página

Tema 1.4 - Interfaces

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();

 }
Última modificación: miércoles, 16 de marzo de 2022, 09:45