2012-09-27 18 views
17

Duplicar posible:
Java Pass Method as Parameter¿Cómo paso el método como parámetro en Java?

¿Es posible pasar de un método como un parámetro en Java? Si no puedo, ¿cuál sería el mejor curso de acción para el siguiente método sin tener que repetir el código?

public void enterUserInput(javax.swing.JTextField inputField, javax.swing.JTextField outputField, method rangeChecking){ 

    String input; 
    double output; 
    input = inputField.getText(); 
    output = Double.parseDouble(input); 
    if(rangeChecking(output)){ 
     outputField.setText(input); 
     inputField.setText(null); 
    } 

me va a llamar a un método rangeChecking de una clase diferente y cada vez que llamo el enterUserInput el método rangeChecking será diferente

+12

[Interfaz - Método de paso de Java como parámetro] (http://stackoverflow.com/questions/2186931/java-pass-method-as-parameter?rq=1) – Aerus

+0

Consulte también esta respuesta http: // stackoverflow. com/a/22933032/1010868 –

Respuesta

6

No es por lo que yo sé. Esto se hace generalmente al hacer una interfaz que tiene el método que desea y pasando una clase que implementa la interfaz de.

public interface IRangeCheck 
{ 
    boolean check(double val); 
} 

public class RangeChecker implements IRangeCheck 
{ 
    public boolean check(double val) 
    { 
     return val > 0.0; 
    } 
} 

... 
    public void blabla(..., IRangeCheck irc) 
    { 
     ... 
     if(irc.check(output)) 
      ... 
    } 
+1

@CrazyCasta .. Eso no es Java ... Debería escribir 'implementa IRangeCheck' para implementar una interfaz .. –

+2

independientemente, el concepto se mantiene .. – jrharshath

+0

@RohitJain Buena captura, ha pasado un tiempo desde De hecho, he escrito algo en Java. – CrazyCasta

32

debe utilizar un interface para hacerlo.

Pasa la interfaz que declara la función deseada al método e invoca el método deseado. El método específico que se invocará es el implementado por la clase implementadora.

Se llama strategy design pattern.

ejemplo de código:

public static interface Foo { //this is the interface declaration 
    public void print(); 
} 
public static class Bar implements Foo { //Bar is an implementing class 
    public void print() { 
     System.out.println("Bar"); 
    } 

} 
public static void test(Foo foo) { //the method accepts an interface 
    foo.print(); //and invokes it, the implementing class' print() will be invoked. 
} 
public static void main(String... args) throws Exception { 
    test(new Bar()); //invoke test() with the class implementing the interface 
} 
+2

Gracias ... aprendí algo nuevo hoy ... :) – Amarnath

+1

Si tuviera que elegir un patrón de diseño que se pareciera a la idea, elegiría el patrón Command. La estrategia parece demasiado compleja para mí, generalmente significa que existen varias implementaciones. –

+0

@amit ¿por qué declaraste la interfaz estática? – Celeritas

6

crear una interfaz con la firma del método, y pasar una subclase anónima de que con su implementación del método.

// the interface that contains the method/methods you want to pass 
interface MethodWrapper { 
    public void method(String s); } 

// ... 
// in your code 
// assuming that "observable" is an object with a method "setCallback" that 
// accepts the callback 
// note that your method implementation will have access to your local variables 

public void someMethodOfYours() { 
    observable.setCallback(new MethodWrapper() { 
     public void method(String s) { 
      System.out.println(s); 
     } } 
    ); 
    // note that your anon subclass will have access to all your contain method 
    // locals and your containing class members, with [some restrictions][1] 
} 

// in the "observable" class - the class that receives the "callback method" 
// ... 

if(updated()) { 
    callback.method("updated!"); } 

En futuras versiones de Java (con el advenimiento de lambdas) que no se tiene que definir la interfaz y la clase interna anónima - habrá sintaxis lambda específica que se compilará el código de bytes a su equivalente.

[1] Cannot refer to a non-final variable inside an inner class defined in a different method

+0

Java 7 no tiene expresiones lambda. Tal vez Java 8 los tendrá alguna vez en el futuro. – Jesper

+0

debidamente anotado - editando la respuesta en consecuencia ... – jrharshath

2

Se puede crear una interfaz que define el método sea necesario, y pasar un objeto de una clase que implementa la interfaz. A menudo, las clases anónimas se utilizan para eso.

interface Worker { 
    public void callMe(); 
} 

public function callWorker(Worker w) { 
    w.callMe(); 
} 

callWorker(new Worker() { 
    public void callMe() { 
     System.out.println("Hi there!"); 
    }); 
1

no se puede pasar el método en java.

lo que hace es declarar una interfaz, y obtener como parámetro una clase que implementa la interfaz, de esta manera puede invocar la función a través del parámetro.

En su código, puede crear una clase anónima.

5

Puede usar reflejo de java.

public void enterUserInput(javax.swing.JTextField inputField, javax.swing.JTextField outputField, String methodName){ 

String input; 
double output; 
input = inputField.getText(); 
output = Double.parseDouble(input); 
Method m = this.getClass().getDeclaredMethod(methodName, Double.class); 

if((Boolean)m.invoke(this, output)){ 
    outputField.setText(input); 
    inputField.setText(null); 
} 
+2

Debe manejar el caso cuando el método requerido pertenece a una clase ancestra y/o el método compatible tiene una firma diferente. 'void foo (double d)' no será igualado por 'getDeclaredMethod' si lo pasa' Double.class'. – Stephan

+1

Realmente debería usar características de lenguaje como la solución con interfaces presentadas por otros en lugar de la reflexión. La reflexión no es segura y es más lenta que las llamadas a métodos regulares. – Jesper

1

No, no es posible pasar los métodos como argumento.

Supongo que lo mejor es crear una interfaz, escribir una clase que implemente eso (modificar la implementación que necesite) y pasar el objeto de la clase como argumento.

También podría utilizar la reflexión, pasar el methodName como una cadena a su método. y usa la reflexión para llamar a ese método.

Esperanza esto ayuda :-)

4

hay maneras que usted puede hacer esto utilizando el Reflection pero eso es mejor evitar. Lo que se quiere hacer es crear una interfaz como:

public interface RangeChecker { 

    boolean rangeChecking(double input); 


} 

luego crear implementaciones para cada uno de los métodos de control de rango:

public class SomeRangeCheck implements RangeChecker { 

    public boolean rangeChecking(double input) { 
     // do something 
    } 

} 

A continuación, la firma de su otro método se convierte en:

public void enterUserInput(JTextField inputField, JTextField outputField, RangeChecker rangeChecking) 

Que puede pasar cualquiera de sus objetos que implementan la interfaz RangeChecker.

Cuestiones relacionadas