1. ホーム
  2. java

JAVAコールバックをクラス間で実行するには?[重複しています]。

2023-09-09 02:21:39

質問

私は、コールバックが非常に簡単である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.");
};

の部分は、Parent クラスで、明らかに正しくないのでは?

どのように解決するのですか?

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

マルチスレッドに注意しましょう。

のコード例です。 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);
        }
    }
}

マルチスレッド

これはマルチスレッドを扱わないことを覚えておいてください。これは別のトピックであり、プロジェクトによってさまざまなソリューションがあります。

オブザーバパターン

observer-patternはほぼ同じことをしますが、大きな違いは ArrayList を使うことです。これが必要ない場合は、1つの参照でより良いパフォーマンスを得ることができます。