Un uso común de las interfaces en Java es cuando quieres tener accesibilidad pública a algún método o atributo de una clase que , por cuestiones de diseño, tiene visibilidad privada o de paquete.
Para ilustrar ésto, en el siguiente ejemplo tenemos la clase Conductor dentro de la clase Coche, ambas dentro del paquete cursojava.Coche:
package cursojava;
public class Coche {
private String marca;
private String modelo;
private Conductor conductor;
public Coche(String marca, String modelo) {
this.marca = marca;
this.modelo = modelo;
conductor = new Conductor("Fernando Alonso");
}
public Conductor getConductor() {
return conductor;
}
public String getMarca() {
return marca;
}
public String getModelo() {
return modelo;
}
// la clase conductor solo tiene accesibilidad en clases que estén en el mismo paquete
class Conductor{
private String nombre;
public Conductor(String nombre) {
this.nombre = nombre;
}
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
}
Desde la clase Principal, ubicada en el paquete cursojava.principal, no podemos acceder al método getNombre de la clase conductor dado que no es accesible al estar en paquetes distintos.
package cursojava.principal;
import cursojava.Coche;
public class Principal {
public static void main(String[] args) {
Coche coche = new Coche("Ferrari", "F10");
//Tanto si intentamos acceder a getConductor creando un nuevo objeto
//de la clase conductor
Conductor conductor = coche.getConductor();
//Como si lo hacemos llamando al atributo conductor de coche
String nombre = coche.getConductor().getNombre();
//nos será imposible acceder al método getnombre
System.out.println(conductor.getNombre());
}
}
Para solucionar este problema nos ayudaremos de un interfaz, que podemos definir en cualquier paquete, teniendo que importarlo si lo definiéramos en otro. Por ejemplo, en nuestro caso crearemos un Interfaz llamado IConductor ubicado en el paquete cursojava.interfaz y lo importaremos en los otros paquetes.
El interfaz lo definiremos de la siguiente forma:
package cursojava.interfaz;
public interface IConductor {
public String getNombre();
}
Y el resto de clases quedarán como sigue (observar los comentarios):
package cursojava;
import cursojava.interfaz.IConductor;
public class Coche {
private String marca;
private String modelo;
private Conductor conductor;
public Coche(String marca, String modelo) {
this.marca = marca;
this.modelo = modelo;
conductor = new Conductor("Fernando Alonso");
}
public Conductor getConductor() {
return conductor;
}
public String getMarca() {
return marca;
}
public String getModelo() {
return modelo;
}
}
// Ahora la clase Conductor implementa al Interface IConductor
class Conductor implements IConductor{
private String nombre;
public Conductor(String nombre) {
this.nombre = nombre;
}
//Debemos de implementar el método getNombre del Interfaz
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
}
package cursojava.principal;
import cursojava.Coche;
import cursojava.interfaz.IConductor;
public class Principal {
public static void main(String[] args) {
Coche coche = new Coche("Ferrari", "F10");
//Ahora accedemos por medio del Interfaz IConductor al método getConductor
IConductor conductor = coche.getConductor();
System.out.println(conductor.getNombre());
}
}