Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 类的回调(非实例)_Java_Oop_Callback_Lwjgl - Fatal编程技术网

Java 类的回调(非实例)

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,

LWJGL 3使用回调系统处理输入,如下所示:

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中的“最佳”方式)。我只是认为它最终是一个额外的不必要的抽象/间接层次。我以前确实试过这样做,但最后我因为它看起来不对劲而感到非常紧张,于是我删除了它。