java 回调(callback)函数简介.


一, 什么是回调函数(callback)

假如类A有1个方法a(), 但是它不知道什么时候调用这个方法a().

而类B告诉类A, 我知道什么时候调用.    那么类A就把自己交给类B(作为类B的一个成员),   当时机适合时, 类B会调用类A的a()方法.

那么a() 就叫回调(callback)方法.


可能我上面的解释不够好,

记住关键两点就得了:

1. 类A 要成为类B的一个成员,    java中是通过接口(interface)来实现的.

2. a()的执行由类B决定, 但是执行的是类A的方法a()




二, 什么要使用回调方法.

是啊, 为什么不直接使用类A来调用a()呢?

实际上这个也涉及层次的问题.


实际上, 类B可以调用类A的方法a(),   但是有时也可以调用其他比如类c的方法c(), 只要类c实现了接口, 替换成类B的成员.


也就是说, 客户端只需要跟类B打交道, 无需知道实际执行的哪个类的哪个方法.


比如一个间公司有1个快递部门(类B), 所有员工都可以找这个快递部门寄快递,   但是实际上这个部门是用顺丰(类A)来快递的.

但是当顺丰快递有问题时,  类B也可以找另一间快递公司,比如EMS(类C)来实现.


那么公司员工就不必与真正的快递公司打交道, 只需把物件交给类B去处理就ok了. 也就是这个过程是动态的. 甚至也可以找另一件公司来实现(类D), 只需要类D实现快递接口.



三, 基于上面快递的一个具体例子

现在我们就基于上面的例子写一段代码.


3.1 UML图



可以见上面有5中角色

分别是:

员工:  Employee

快递部门: ExDepartment

回调(快递)接口: Callbackable

具体快递公司: SFExpress & EMS


下面是具体代码:


3.2 Callbackable

这个接口只需要定义1个回调方法method()

public interface Callbackable {
	public void method();
}



3.3 ExDepartment

同样地, 快递部门类必须预留1个接口成员.

它可以选择1个实现了Callbackable接口的对象作为自己的成员,

public class ExDepartment {
	private Callbackable exCompany;

	public void setExCompany(Callbackable exCompany) {
		this.exCompany = exCompany;
	}
	
	public ExDepartment(Callbackable exCompany){
		this.setExCompany(exCompany);
	}
	
	public void sendGoods(){
		exCompany.method();
	}
}

这个部门有1个快递方法sendGoods(), 但是实际上是调用这个快递公司成员的回调方法.method();



3.4 SFExpress

具体的快递公司类顺丰, 必须实现Callbackable接口,

并重写里面回调方法.

public class SFExpress implements Callbackable{

	public void SFSendGoods(){
		System.out.println("Sent goods by SF!");
	}
	
	@Override
	public void method() {
		// TODO Auto-generated method stub
		this.SFSendGoods();
	}
	
}


3.5 EMS

同上

public class EMS implements Callbackable {
	public void EMSSendGoods(){
		System.out.println("Sent GOods by EMS");
	}
	
	@Override
	public void method() {
		// TODO Auto-generated method stub
		this.EMSSendGoods();
	}
	
}


3.6 Employee

员工类, 无需知道具体快递公司的存在, 只需要跟快递部门打交道就ok了

public class Employee {
	public void sendGoods(ExDepartment exd){
		exd.sendGoods();
	}
}


3.7 客户端代码和输出:

		ExDepartment exd = new ExDepartment(new SFExpress());
		
		Employee jack = new Employee();
		jack.sendGoods(exd);
		
		exd.setExCompany(new EMS());
		jack.sendGoods(exd);
		
		exd.setExCompany(new Callbackable() {
							@Override
							public void method(){
								System.out.println("Sent goods by Jimmy!");
							}
						});
		
		jack.sendGoods(exd);


输出:

Sent goods by SF!
Sent GOods by EMS
Sent goods by Jimmy!


可以见到, 员工寄了3次快递, 第一次是顺丰, 第一次是EMS, 但是第三次是某个人(可能两个快递公司都放假, 随便找个人来送)


这个模型的好处时,

无论有什么具体快递类的修改, 只需要修改快递类本身.

而增加快递公司类, 只需让那个类实现回调接口, 而员工类和快递部门类都无需修改的.



四, java的控件事件方法也是用回调来实现的.

上面的代码有这么一段:

exd.setExCompany(new Callbackable() {
							@Override
							public void method(){
								System.out.println("Sent goods by Jimmy!");
							}
						});

上面用到了内部类的方法.

是不是觉得有d面善.


这种写法跟java的button事件定义优点类似.

下面是新建1个button的例子:

JButton btnNewButton = new JButton("New button");
		btnNewButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
			}
		});



其中btnNewButton就相当于上面例子的快递部门ExDepartment

而ActionListener实际上就是1个回调接口. (在这里也叫监听器)

而actionPerFormed就是1个回调方法.



没错, java界面(awt/swt)的控件事件就是通过回调来实现的.


你们想想, 一个button,  按下去做什么不是固定的.

有的button触发 行为a(), 有些触发行为b()

所以, 我们让行为b()写成回调方法, 也就是所让它所需的类实现 回调接口ActionListener().


这样, 就可以很灵活地为每1个button定义不同的触发行为了!













































  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Java中,回调函数Callback)是一种常见的编程模式。回调函数用于在某个特定事件发生时,将控制权交给另一个函数或对象,以执行特定的操作。这种模式通常用于异步编程或事件驱动的编程中。 在Java中,可以通过接口、抽象类或Lambda表达式来实现回调函数。下面是几种常见的实现方式: 1. 使用接口: - 定义一个回调接口,其中含一个回调方法。 - 在需要执行回调的类中,将需要回调的对象作为参数传入,并调用回调方法。 2. 使用抽象类: - 定义一个抽象类,其中含一个抽象的回调方法。 - 在需要执行回调的类中,继承该抽象类并实现回调方法。 3. 使用Lambda表达式(Java 8及以上版本): - 定义一个函数式接口,其中含一个抽象的回调方法。 - 在需要执行回调的地方,使用Lambda表达式创建接口的实例并实现回调方法。 以下是一个使用接口实现回调函数的示例代码: ```java // 定义回调接口 interface Callback { void onCallback(); } // 执行回调的类 class Caller { void doSomething(Callback callback) { // 执行某些操作 System.out.println("Doing something..."); // 执行回调 callback.onCallback(); } } // 使用回调的类 class CallbackHandler implements Callback { @Override public void onCallback() { System.out.println("Callback executed!"); } } // 测试代码 public class Main { public static void main(String[] args) { Caller caller = new Caller(); CallbackHandler callbackHandler = new CallbackHandler(); caller.doSomething(callbackHandler); } } ``` 运行以上代码,将会输出以下结果: ``` Doing something... Callback executed! ``` 这里的`CallbackHandler`实现了`Callback`接口,并在回调方法中定义了需要执行的操作。在`Caller`类中调用`doSomething`方法时,将`callbackHandler`对象作为参数传入,然后执行回调方法。 这只是回调函数的一种简单实现方式,实际使用中可以根据具体的场景和需求选择合适的实现方式。希望以上信息对你有所帮助!如果你有任何问题,可以继续提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

nvd11

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值