私は、コールバックが非常に簡単な 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
インターフェースを定義し、コールバックを受信するクラスに実装します。
あなたの場合はマルチスレッドに注意してください。
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 つの参照でパフォーマンスが向上します。