Las interfaces son una implementación de los lenguajes de programación orientados a objetos que sustituyen a la herencia múltiple y son una técnica muy utilizada por lo que hay que dominarlas.
Una interfaz es un tipo de clase que solo declara métodos abstractos y variables estáticas. Su tarea es indicarnos lo que deben hacer las clases que la implementan, sin especificar como deben hacerlo.
Las clases pueden implementar mas de una interfaz. Y debemos seguir una sola regla: Todos los métodos declarados en la interfaz deben estar implementados en las clases que implementan la interfaz.

Es recomendable crear una interfaz en un archivo distinto. Y al igual que las clases, el nombre del archivo debe ser el mismo que el de la interfaz; en este caso el archivo se llama Geometria.java.
La interfaz Geometria será implementada por las clases Circulo y Cuadrado.

Como mencioné al inicio; una interfaz nos indica lo que deben hacer las clases pero no como hacerlo. En esta caso la interfaz Geometria nos indica que las clases Circulo y Cuadrado realizarán los cálculos para obtener el área, perímetro y el nombre de las figuras; pero no nos especifica como hacerlo ya que los calculos para ambas figuras son distintos, al igual que el nombre.
El código completo queda de la siguiente forma con los cuatro archivos respectivamente: Geometria.java,Circulo.java, Cuadrado.java y Test.java.
Código para el archivo Geometria.java
package org.snippetstricks.oop;
public interface Geometria {
public static final double PI = 3.14159265;
public double area();
public double perimetro();
public String nombre();
}
Código para el archivo Circulo.java
package org.snippetstricks.oop;
public class Circulo implements Geometria {
private double radio = 0;
public Circulo(double r) {
this.radio = r;
}
public double area() {
return PI * radio * radio;
}
public double perimetro() {
return 2.0 * PI * radio;
}
public String nombre() {
return "Circulo";
}
}
Código para el archivo Cuadrado.java
package org.snippetstricks.oop;
public class Cuadrado implements Geometria {
private double lado = 0;
public Cuadrado(double l) {
this.lado = l;
}
public double area() {
return lado * lado;
}
public double perimetro() {
return 4.0 * lado;
}
public String nombre() {
return "Cuadrado";
}
}
Código para el archivo Test.java
package org.snippetstricks.oop;
public class Test {
static void resultados(Geometria figura) {
System.out.printf("Los datos de la figura %s son:%n", figura.nombre());
System.out.printf("El perimetro es: %f%n", figura.area());
System.out.printf("El area es: %f%n", figura.perimetro());
}
public static void main(String[] args) {
Circulo circulo = new Circulo(10);
Cuadrado cuadrado = new Cuadrado(20);
resultados(circulo);
resultados(cuadrado);
}
}
Para probar el ejemplo creamos el archivo Test.java donde declaramos el método resultados que tiene como argumento la interfaz Geometria con el nombre figura. Este argumento utiliza los métodos perimetro(), area() ynombre() de las clases Circulo y Cuadrado.
Ahora compilemos y ejecutemos el ejemplo.
> javac -d . *.java > java org.snippetstricks.oop.Test Los datos de la figura Circulo son: El perimetro es: 314.159265 El area es: 62.831853 Los datos de la figura Cuadrado son: El perimetro es: 400.000000 El area es: 80.000000