函数回调几乎是所有编程语言里都需要学习的地方,也是一个重点,因为在写库的时候,在服务器与客户端数据传递的时候我们都会涉及这方面的知识。
在C和C++中实现的方法是用函数指针,而Java里的实现是用接口Interface,其实如果我们把接口的对象看成是一个函数指针也许理解起来就是一样的了。
举个例子:
服务器和客户端的例子。直接用Java2SE模拟一个Server和Client类,然后定义一个接口用于消息传递——CallBackInterface
public interface CallBackInterface { public void receiveMessage(String message); }
Server端代码:
public class Server { private CallBackInterface callBackInterface; public Server() {} public void setCallBack(CallBackInterface cbl) { this.callBackInterface = cbl; } public void sendMessage(String msg) { callBackInterface.receiveMessage(msg); } }
可以看出来Server端有一个CallBackInterface私有成员,而在setCallBack方法中,我们给这个私有成员赋值了,而这个值可以想到应该是来自Client端的。
后面又有一个sendMessage方法,在这个方法中,调用了实例化后的私有成员的receiveMessage方法,显然这个receiveMessage方法是Client继承了CallBackInterface接口后继承下来的方法,因此之前setCallBack传进来的值应该是Client实例。
Client端代码:
public class Client implements CallBackInterface { public static void main(String[] args) { Server server = new Server(); Client client = new Client(); server.setCallBack(client); server.sendMessage("Server send Client a message"); } @Override public void receiveMessage(String message) { // TODO Auto-generated method stub System.out.println("Client receive a message: " + message); } }代码中Server实例调用了setCallBack方法,传入的参数果然是Client实例,而后这个Client实例的receiveMessage方法被Server端的私有成员调用,这个机制是属于Java的多态里面的。而Server端的私有接口成员就类似于函数指针一样。
Server实例调用了sendMessage后传入了一个字符串,而在sendMessage方法中,这个字符串又交个了Client的receiveMessage方法。最后自然在System.out.println里输出了:
代码结果:Client receive a message: Server send Client a message
Client端你可以可以采用这样的写法:将CallBackInterface接口对象实例化并且这个对象是归属于Client类的,而不是Client继承CallBackInterface接口。最后传入到setCallBack方法中。结果是一样的!
public class Client { public static void main(String[] args) { Server server = new Server(); Client client = new Client(); CallBackInterface cbi = new CallBackInterface() { @Override public void receiveMessage(String message) { // TODO Auto-generated method stub System.out.println("Client receive a message: " + message); } }; server.setCallBack(cbi); server.sendMessage("Server send Client a message"); } }