将方法引用传递给对象构造函数

时间:2016-08-27 20:16:28

标签: java parameter-passing simplify

我觉得我在静态类型语言方面缺少一些东西。当我几乎只使用perl方式时,有很多方法可以告诉对象哪个函数可以调用。

既然我是Java,我就无法看到如何以简单的方式做类似的事情

我有一个通用的Button类。这是所有将要使用的实际按钮的子类:每个按钮在单击时都有不同的方法。

单击时是否真的无法将引用传递给要调用的方法,以便我可以为所有按钮使用一个类?

目前,我创建了这样的按钮:

// Specifically using the subclass that sets "firemode" to "close"
FiremodeClose fc = new FiremodeClose(Settings.ui_panel_start, Settings.ui_panel_row_firemode, game);
painter.addSelectionButton(fc);
clickTracker.addSelectionButton(fc);

这个课程涉及无数的子类,每个子类只在位置,标签/图形和方法调用方面有所不同。做类似的事情更有意义:

// Generic button, the method that sets "firemode" is somehow passed as arguement to the contsructor.
Button fc = new Button(&referenceToFunctionToCallWhenClicked, otherArguementsEtc);
painter.addSelectionButton(fc);
clickTracker.addSelectionButton(fc);

就像我说的那样,我觉得我必须遗漏一些东西,因为它应该有一种方法来实现这一点,因此让我只使用一个Button类而没有任何子类。

3 个答案:

答案 0 :(得分:1)

您可以使用Runnable

class MyButton {
    private final Runnable action;

    public MyButton(Runnable action) {
        this.action = action;
    }
    ...
}

然后在点击按钮时调用action.run()

然后在创建按钮时,只要它具有void返回类型,就可以传递reference to a method,并且不带任何参数。

Button fc = new Button(EnclosingClass::methodToCall, otherArguementsEtc);

其他接口可用于不同的方法签名。

答案 1 :(得分:1)

在Java 8中,您可以使用方法引用和lambdas:

class Button {
    Button(Runnable function) {
    }
}
Button b1 = new Button(() -> System.out.println("works!"));
Button b2 = new Button(System::gc);

你可以在Java< 8中做类似的事情,但是对于匿名类来说它更冗长:

Button b3 = new Button(new Runnable() {
    @Override
    public void run() {
        System.out.println("works!");
    }
});

答案 2 :(得分:1)

  

如果那是什么接口,那么我必须将它们用于除了预期目的之外的其他东西。我很乐意看到一个涉及一些代码示例的答案。

Buttons实施observer pattern,就像Swing does一样。然后你甚至可以使用Swing的ActionListener界面,甚至Runnable也不是一个糟糕的选择,或者例如滚动你自己:

// Your interface.
public interface MyButtonListener {
    public void buttonClicked ();
}

// Somewhere else:
Button fc = ...;
fc.addButtonListener(new MyButtonListener () {
    @Override public void buttonClicked () {
        // do stuff here
    }
});

// And in your Button have it simply iterate through all of its registered
// MyButtonListeners and call their buttonClicked() methods.

有许多其他方法可以实现这一点。例如,您甚至可以执行以下操作:

public interface ThingThatCaresAboutButtons {
    public void buttonClicked (Button button);
}

然后让您的更高级别的UI逻辑类似于:

public class MyUI implements ThingThatCaresAboutButtons {
    @Override public void buttonClicked (Button button) {
        if (button == theOneButton) {
            // do whatever
        } else if (button == theOtherButton) {
            // do whatever
        }
    }
}

创建按钮时:

theOneButton = new Button(theUI, ...);
theOtherButton = new Button(theUI, ...);

或者让它们维护一个列表而不是构造函数中传递的单个对象。或者其他什么。

给这只猫皮肤的无尽方法,但希望你在这里得到一些灵感。看看Swing是如何工作的。