"Punteros a métodos" en Java
Una de las cosas que extrañaba de C en Java es la capacidad de apuntar a una función. En lugar de invocar a una función directamente, podía hacerlo a través de una variable. Esto es: no importa a qué apunta a esa variable, cuando se invoca con los parámetros correctos, lo ejecutará.
En Java lo más cercano que se podía hacer era usando polimorfismo. A partir de Java 8 apareció lo que veremos en este post.
Consideremos este pequeño código en C.
Al ejecutarse esta es la salida:
La misma invocación, pero ejecuciones diferentes.
Si lo pensamos en Java, lo más parecido sería tener un método
(Sí, mucho código para hacer lo mismo). La ejecución muestra el mismo resultado.
Ahora bien, se puede hasta reducir un poco más el código evitando crear las clases, solo implementamos la interfaz directamente:
Ya, tenemos menos código... pero aún estamos dependiendo de una interfaz. La cuestión es que, si quiero ejecutar un método que lo definí en alguna clase y no necesito crear una interfaz para ejecutar dependiendo de la implementación... ¿cómo lo hago?
Ahora, vamos a instanciar esas dos clases, serán dos objetos diferentes. Pero queremos, por alguna razón de nuestra lógica, invocar a esos métodos, pero el que lo invoca no sabrá a quién está ejecutando.
Para poder implementar, debemos utilizar la interfaz Consumer, y le decimos cuál es el parámetro que va a tener:
Y, para ejecutarlo, debemos pasarle la variable seguido de un par de dos puntos
Ahora bien, para ejecutar el método podría ser así:
Ahora bien, ejecutemos el código, le pasamos el método de la misma manera.
Nuestras clases a probar:
Ahora, ejecutaremos para ejecutar será:
y la ejecución será así:
En Java lo más cercano que se podía hacer era usando polimorfismo. A partir de Java 8 apareció lo que veremos en este post.
Consideremos este pequeño código en C.
Al ejecutarse esta es la salida:
La misma invocación, pero ejecuciones diferentes.
Si lo pensamos en Java, lo más parecido sería tener un método
abstract
(como de interface o de una clase abstracta) y dependiendo de su instanciación podremos tener el resultado diferente:
(Sí, mucho código para hacer lo mismo). La ejecución muestra el mismo resultado.
Ahora bien, se puede hasta reducir un poco más el código evitando crear las clases, solo implementamos la interfaz directamente:
Ya, tenemos menos código... pero aún estamos dependiendo de una interfaz. La cuestión es que, si quiero ejecutar un método que lo definí en alguna clase y no necesito crear una interfaz para ejecutar dependiendo de la implementación... ¿cómo lo hago?
Dos clases diferentes, dos métodos diferentes
Supongamos que tengamos dos clases, que en lo único que coinciden es un método que tienen la misma cantidad de parámetros. No tienen los mismos nombres, porque el diseño de mi aplicación funciona así (así que implementar una interfaz queda fuera). Estas clases son:Ahora, vamos a instanciar esas dos clases, serán dos objetos diferentes. Pero queremos, por alguna razón de nuestra lógica, invocar a esos métodos, pero el que lo invoca no sabrá a quién está ejecutando.
Para poder implementar, debemos utilizar la interfaz Consumer, y le decimos cuál es el parámetro que va a tener:
static void run(Consumer<Integer> c) { c.accept(10); //invoca el método, con el mismo parámetro }
Y, para ejecutarlo, debemos pasarle la variable seguido de un par de dos puntos
::
y seguido el nombre del método:
Quiero obtener un valor
Hasta aquí fue un ejemplo invocando un método con un parámetro... pero ahora solo quiero invocar un método que me devuelva un valor. Vamos, tenemos estás clases:Ahora bien, para ejecutar el método podría ser así:
static String run(Supplierm) { return m.get(); //ejecuta el método cuando se le pasa }
Ahora bien, ejecutemos el código, le pasamos el método de la misma manera.
Pasar parámetro, obtener resultado
Ahora se pone interesante: pasarle un parámetro, y obtener un valor. Para eso usaremos FunctionNuestras clases a probar:
Ahora, ejecutaremos para ejecutar será:
static String run(Function<String, String> f, String p) { return f.apply(p); //ejecuta la funcion con el parametro y lo devuelve }
y la ejecución será así:
Comentarios
Publicar un comentario
Si quieres hacer una pregunta más específica, hazla en los foros que tenemos habilitados en Google Groups
Ah! solo se permiten comentarios de usuarios registrados. Si tienes OpenID, bienvenido! Puedes obtener su OpenID, aquí: http://openid.net/