A continuación, mostramos un ejemplo muy sencillo, pero que transmite mucha información en poco espacio de tiempo.
Véase el siguiente caso: nos piden definir una interfaz con un método habla, base a partir de la cual vamos a resolver bastantes preguntas del lenguaje:
La definición es la siguiente:
package javahispano.scjp; public interface Hablable { void habla(); }
Recordamos que al ser interfaz, el método es abstracto y público. ¿Qué significa esto? Que todas las clases pueden verlo (incluídas aquellas que implementan la interfaz), y que no tiene definición, esto es, que sólo hemos definido la cabecera del método, siendo obligatorio la definición de la clase por la clase que implemente dicha interfaz.
La misma definición (algo más redundante), es la siguiente:
package javahispano.scjp; public interface Hablable { public abstract void habla(); }
Al ser una interfaz, la clase que implemente dicha interfaz tiene la obligación de definir el método. Esto es:
package javahispano.scjp; public class EjercicioDePrueba implements Hablable{ }
Esta clase falla en compilación, indicando que falta implementar un método, por lo cual, sería correcto tener algo parecido a lo siguiente:
package javahispano.scjp; public class EjercicioDePrueba implements Hablable{ public void habla() { System.out.println("Hey que pasa chavalit@s"); } }
¿Qué pasaría si yo hago lo siguiente en la interfaz?
package javahispano.scjp; public interface Hablable { private abstract void habla(); }
Lo primero, que la interfaz no compila PUES SÓLO ADMITE MÉTODOS PÚBLICOS Y ABSTRACTOS, CON EL OBJETIVO DE QUE LAS CLASES QUE IMPLEMENTEN DICHOS MÉTODOS TENGAN VISIBILIDAD Y DEFINAN DICHOS MÉTODOS.
Por otro lado, podría hacer una extensión de la clase anterior, y definir algo como lo siguiente:
package javahispano.scjp; public class EjercicioDeExtension extends EjercicioDePrueba { public void habla() { System.out.println("Hey que pasa chavalit@s, aqui tiramos de EjercicioDeExtension"); } }
Y después, crear un método main:
public static void main (String args[]){ EjercicioDeExtension ejercicioDeExtension = new EjercicioDeExtension(); EjercicioDePrueba ejercicioDePrueba = new EjercicioDePrueba(); Listhablables = new ArrayList (); hablables.add(ejercicioDeExtension); hablables.add(ejercicioDePrueba); hablables.get(0).habla(); hablables.get(2).habla(); ejercicioDeExtension.habla(); ejercicioDePrueba.habla(); }
La pregunta es: ¿compilaría este método? La respuesta es SI, estamos haciendo uso de polimorfismo. ¿Otra pregunta, cuál sería la salida del método? La respuesta, si habéis estado atentos, es la siguiente:
Hey que pasa chavalit@s, aqui tiramos de EjercicioDeExtension
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 2, Size: 2
at java.util.ArrayList.RangeCheck(ArrayList.java:546)
at java.util.ArrayList.get(ArrayList.java:321)
at javahispano.scjp.EjercicioDeExtension.main(EjercicioDeExtension.java:20)
Porque NOS HEMOS EXCEDIDO EN LAS POSICIONES!!
Ok, corrigiendo este error, sustituiríamos la línea:
hablables.get(2).habla();
Por la línea:
hablables.get(1).habla();
Entonces, ¿cuál sería la salida?
La respuesta es la siguiente:
Hey que pasa chavalit@s, aqui tiramos de EjercicioDeExtension
Hey que pasa chavalit@s
Hey que pasa chavalit@s, aqui tiramos de EjercicioDeExtension
Hey que pasa chavalit@s
Pues la JVM, en tiempo de ejecución, CONOCE LA CLASE QUE TENEMOS EN EL OBJETO APUNTADO POR LA INTERFAZ, y utiliza el método más cercano a dicha clase: esto es, si existe ese método en esa clase, utilizamos dicho método, si no, buscamos en la clase padre y así hasta llegar a la clase Object. Si el método no existiera, hubiera dado un fallo en compilación.
En principio aquí lo dejamos chavalit@s.....