valor - llamar variable de otra clase java
¿Cómo realizo una devolución de llamada JAVA entre clases? (5)
Defina una interfaz e impleméntela en la clase que recibirá la devolución de llamada.
Preste atención al multihilo en su caso.
Ejemplo de código de 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);
}
}
En su caso, además de multi-threading, podría hacer esto:
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);
}
}
}
Multi-threading
Recuerde que esto no maneja el multi-threading, este es otro tema y puede tener varias soluciones dependiendo del proyecto.
El patrón de observador
El patrón de observación hace casi esto, la principal diferencia es el uso de una ArrayList
para agregar más de un oyente. Donde esto no es necesario, obtienes un mejor rendimiento con una referencia.
Esta pregunta ya tiene una respuesta aquí:
- Funciones de devolución de llamada en Java 16 respuestas
Vengo de JavaScript, en el que las devoluciones de llamada son bastante fáciles. Estoy tratando de implementarlos en JAVA, sin éxito.
Tengo una clase para padres:
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...");
}
}
Luego tengo una clase para niños, que se llama desde el padre:
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) {
}
}
¿Cuál es la forma correcta de implementar el
serverConnectionHandler.newConnection = function(Socket _socket) {
System.out.println("A function of my child class was called.");
};
parte, en la clase de Padres, que claramente no es correcto?
En este caso particular, lo siguiente debería funcionar:
serverConnectionHandler = new ServerConnections(_address) {
public void newConnection(Socket _socket) {
System.out.println("A function of my child class was called.");
}
};
Es una subclase anónima.
No sé si esto es lo que estás buscando, pero puedes lograrlo pasando una devolución de llamada a la clase infantil.
primero defina una devolución de llamada genérica:
public interface ITypedCallback<T> {
void execute(T type);
}
crear una nueva instancia de ITypedCallback en la instanciación de ServerConnections:
public Server(int _address) {
serverConnectionHandler = new ServerConnections(new ITypedCallback<Socket>() {
@Override
public void execute(Socket socket) {
// do something with your socket here
}
});
}
llama al método de ejecución en el objeto de devolución de llamada.
public class ServerConnections implements Runnable {
private ITypedCallback<Socket> callback;
public ServerConnections(ITypedCallback<Socket> _callback) {
callback = _callback;
}
@Override
public void run() {
try {
mainSocket = new ServerSocket(serverPort);
while (true) {
callback.execute(mainSocket.accept());
}
} catch (IOException ex) {
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
BTW: No revisé si es 100% correcto, aquí lo codifiqué directamente.
OMI, debería echarle un vistazo al Patrón de Observador , y así es como trabajan la mayoría de los oyentes
Usa el patrón de observador. Funciona así:
interface MyListener{
void somethingHappened();
}
public class MyForm implements MyListener{
MyClass myClass;
public MyForm(){
this.myClass = new MyClass();
myClass.addListener(this);
}
public void somethingHappened(){
System.out.println("Called me!");
}
}
public class MyClass{
private List<MyListener> listeners = new ArrayList<MyListener>();
public void addListener(MyListener listener) {
listeners.add(listener);
}
void notifySomethingHappened(){
for(MyListener listener : listeners){
listener.somethingHappened();
}
}
}
Usted crea una interfaz que tiene uno o más métodos para llamar cuando ocurre algún evento. Entonces, cualquier clase que necesita ser notificada cuando ocurren eventos implementa esta interfaz.
Esto permite más flexibilidad, ya que el productor solo conoce la interfaz del oyente, no una implementación particular de la interfaz del oyente.
En mi ejemplo:
MyClass
es el productor aquí al notificar una lista de oyentes.
MyListener
es la interfaz.
MyForm
está interesado en cuando somethingHappened
MyListener
, por lo que está implementando MyListener
y registrándose con MyClass
. Ahora MyClass
puede informar a MyForm
sobre eventos sin hacer referencia directa a MyForm
. Esta es la fuerza del patrón del observador, reduce la dependencia y aumenta la reutilización.