Java 类的回调(非实例)
LWJGL 3使用回调系统处理输入,如下所示:Java 类的回调(非实例),java,oop,callback,lwjgl,Java,Oop,Callback,Lwjgl,LWJGL 3使用回调系统处理输入,如下所示: public class Main { ... public static void main(String[] args) { glfwSetKeyCallback(window, keyCallback = new GLFWKeyCallback() { @Override public void invoke(long window,
public class Main
{
...
public static void main(String[] args)
{
glfwSetKeyCallback(window, keyCallback = new GLFWKeyCallback()
{
@Override
public void invoke(long window, int key, int scancode, int action, int mods)
{
}
});
}
}
<>但是,我不希望在代码的中间处理我的输入,另一个目的。
我可以使用GLFWKeyCallback扩展一个类,并将该类的实例传递给glfwSetKeyCallback(),但我不是从实例中执行该函数。它是从静态函数(main)运行的。我不希望将代码从main-in移动到实例化对象,因为它与我的编码风格冲突,这会使我感到压力,最终我会放弃并撤消它
我现在的情况是这样的:
public class Main
{
private static GLFWKeyCallbackProxy glfwKeyCallbackProxy;
public static void main(String[] args)
{
glfwSetKeyCallback(window, glfwKeyCallbackProxy);
}
}
public class GLFWKeyCallbackProxy extends GLFWKeyCallback
{
@Override
public void invoke(long window, int key, int scancode, int action, int mods)
{
// Communicate back to Main
}
}
我真的不喜欢这个,因为GLFWKeyCallbackProxy现在正在实现游戏的一部分,而不仅仅是被游戏使用。我相信它不符合良好的OOP结构,并且具有紧密耦合
理想情况下,我的解决方案应该在某种程度上等同于这个假设代码:
public class Main extends GLFWKeyCallback
{
public static void main(String[] args)
{
glfwSetKeyCallback(window, ???);
}
@Override
public static void invoke(long window, int key, int scancode, int action, int mods)
{
// This function now resides along side the code dealing with the rest of the game.
}
}
本质上,我希望回调函数将静态类级函数视为一个实例,即使它不是
您将如何实现这一点,或者我将不得不求助于一些紧耦合,就像上面的解决方案一样
编辑:我忘了提到,在任何解决方案中,我都需要访问GLFWKeyCallback的内部。让我们假设我不能纯粹通过引用(通过publics或getter/setter)访问这些内部构件
我最终选择的解决方案是:
public class Game
{
static long window;
public static void keyboardInvoke(long window, int key, int scancode, int action, int mods)
{
}
public static void mouseInvoke(long window, int button, int action, int mods)
{
}
public static void main(String[] args)
{
glfwSetKeyCallback(window, GLFWKeyCallback(Game::keyboardInvoke));
glfwSetMouseButtonCallback(window, GLFWMouseButtonCallback(Game::mouseInvoke));
}
}
我的第一个建议是开始使用“在代码中间处理输入的另一个目的”。p> 现在,如果您真的不想这样做,那么您可以尝试以下方法:
public class Main
{
public static void main(String[] args)
{
glfwSetKeyCallback(window, new GLFWKeyCallbackProxy());
}
class GLFWKeyCallbackProxy extends GLFWKeyCallback
{
@Override
public void invoke(long window, int key, int scancode, int action, int mods)
{
// Communicate back to Main
}
}
}
您的内部类将有权访问包含类的成员,因此您应该没有问题
但是我最强烈建议你考虑的建议是转到java 8,在那里你将能够做这样的事情:
public class Main
{
public static void main(String[] args)
{
glfwSetKeyCallback( window, Main::invoke );
}
void invoke(long window, int key, int scancode, int action, int mods)
{
// Communicate back to Main
}
}
…因此invoke()成为Main的成员方法,一切都很美好
另外,最后一条建议与当前问题无关:永远不要在static main()中编写任何重要代码。main()应该做的第一件(也是唯一一件)事情是实例化一个对象并将控制权传递给它。这是一个好主意,到目前为止我更喜欢这样做,我可能可以接受。我更希望它不在类中,因为它不是打算重用或交换出去的东西,等等。我也不想通过单例/某些模式强制实现这一点。但我想我可能会受到语言限制的摆布。谢谢。我将继续等待其他建议一段时间。是的,当然,一定要等着看其他人怎么说,StackOverflow上有很多才华横溢的人。(我刚刚看到了你的编辑)好吧,Java 8东西只有在
GLFWKeyCallback
是一个单一方法接口的情况下才能工作,结果证明它不适用于这种特殊情况。我完全忘记了Java8是一种东西!!实际上,我还没有看过这些新东西,我很高兴看到Main::invoke是什么。编辑:即使不能解决问题,也会很兴奋。不过我不同意你的最后一点(我理解这是否是Java/OOP中的“最佳”方式)。我只是认为它最终是一个额外的不必要的抽象/间接层次。我以前确实试过这样做,但最后我因为它看起来不对劲而感到非常紧张,于是我删除了它。