我觉得我在静态类型语言方面缺少一些东西。当我几乎只使用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
类而没有任何子类。
答案 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是如何工作的。