クラス間で JAVA コールバックを実行するにはどうすればいいですか? [重複] 質問する

クラス間で JAVA コールバックを実行するにはどうすればいいですか? [重複] 質問する

私は、コールバックが非常に簡単な JavaScript から来ました。それを JAVA に実装しようとしていますが、うまくいきません。

親クラスがあります:

import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Server {
    ExecutorService workers = Executors.newFixedThreadPool(10);
    private ServerConnections serverConnectionHandler;

    public Server(int _address) {
        System.out.println("Starting Server...");
        serverConnectionHandler = new ServerConnections(_address);

        serverConnectionHandler.newConnection = function(Socket _socket) {
            System.out.println("A function of my child class was called.");
        };

        workers.execute(serverConnectionHandler);

        System.out.println("Do something else...");
    }
}

次に、親から呼び出される子クラスがあります。

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;

public class ServerConnections implements Runnable {
    private int serverPort;
    private ServerSocket mainSocket;

    public ServerConnections(int _serverPort) {
        serverPort = _serverPort;
    }

    @Override
    public void run() {
        System.out.println("Starting Server Thread...");

        try {
            mainSocket = new ServerSocket(serverPort);

            while (true) {
                newConnection(mainSocket.accept());
            }
        } catch (IOException ex) {
            Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void newConnection(Socket _socket) {

    }
}

正しい実装方法は何ですか?

serverConnectionHandler.newConnection = function(Socket _socket) {
    System.out.println("A function of my child class was called.");
};

親クラスのどの部分が明らかに正しくありませんか?

ベストアンサー1

インターフェースを定義し、コールバックを受信するクラスに実装します。

あなたの場合はマルチスレッドに注意してください。

コード例http://cleancodedevelopment-qualityseal.blogspot.com.br/2012/10/understanding-callbacks-with-java.html

interface CallBack {                   

//declare an interface with the callback methods, 
//so you can use on more than one class and just 
//refer to the interface

    void methodToCallBack();
}

class CallBackImpl implements CallBack {          

//class that implements the method to callback defined 
//in the interface

    public void methodToCallBack() {
        System.out.println("I've been called back");
    }
}

class Caller {

    public void register(CallBack callback) {
        callback.methodToCallBack();
    }

    public static void main(String[] args) {
        Caller caller = new Caller();
        CallBack callBack = new CallBackImpl();       

//because of the interface, the type is Callback even 
//thought the new instance is the CallBackImpl class. 
//This alows to pass different types of classes that have 
//the implementation of CallBack interface

        caller.register(callBack);
    }
} 

あなたの場合、マルチスレッドとは別に、次のようにすることができます。

interface ServerInterface {
    void newSeverConnection(Socket socket);
}

public class Server implements ServerInterface {

    public Server(int _address) {
        System.out.println("Starting Server...");
        serverConnectionHandler = new ServerConnections(_address, this);
        workers.execute(serverConnectionHandler);
        System.out.println("Do something else...");
    }

    void newServerConnection(Socket socket) {
        System.out.println("A function of my child class was called.");
    }

}

public class ServerConnections implements Runnable {

    private ServerInterface serverInterface;
    
    public ServerConnections(int _serverPort, ServerInterface _serverInterface) {
      serverPort = _serverPort;
      serverInterface = _serverInterface;
    }

    @Override
    public void run() {
        System.out.println("Starting Server Thread...");

        if (serverInterface == null) {
            System.out.println("Server Thread error: callback null");
        }

        try {
            mainSocket = new ServerSocket(serverPort);

            while (true) {
                serverInterface.newServerConnection(mainSocket.accept());
            }
        } catch (IOException ex) {
            Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

マルチスレッド

これはマルチスレッドを処理しないことに注意してください。これは別のトピックであり、プロジェクトに応じてさまざまなソリューションがあります。

観察者パターン

オブザーバー パターンはこれとほぼ同じことを行いますが、主な違いは、ArrayList複数のリスナーを追加するために を使用することです。これが不要な場合は、1 つの参照でパフォーマンスが向上します。

おすすめ記事