关于java回调函数的理解

本文通过一个生动的例子,详细解释了回调函数的工作原理及其在实际应用中的实现方式。以司令与间谍的故事为主线,介绍了如何利用接口来实现回调机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

网上看了许多关于回调函数的例子及理解,发现很多都是为了说明回调而写的回调,当然,例子简单明了,也很能说明问题,但是要在实际中使用的时候很多人还是一头雾水。这里用我个人的理解并配上一些个人总结的例子来加以说明。


首先说一下回调函数的基本两个成员,一个是调用方,一个是被调用方。


被调用方(Service 服务类简称S):里面可以有一个或多个用于服务于B的方法。

调用方(BOSS 就叫老板吧 简称B):可以是任何有需要S服务的类,这里有一个回调方法,用于S服务类在服务过程中或服务完时调用。

在这里有两个问题:

1、S服务方法中要怎样才能调用B中的回调方法,这里只能让S持有B对象,在B调用服务方法前调用将自己对象传入到S中。

2、S服务方法中要怎么知道调用B的哪个回调方法。

这里解决办法就是用接口(这里用IS表示),并在接口中定义回调方法。这样在S服务方法中就只需要持有接口类型即可,并在调用回调方法时调用接口中的回调方法就行了。有需要调用S服务的类就必须实现S服务指定的接口IS并实现里面的方法。(这里有点啰嗦,主要还是考虑基础比较差的)。

这里举个通俗的例子,也希望读者能加深接口的理解。

司令B 和 间谍S例子:

间谍S只会一件事,就是看敌方有没坦克。

司令B想让间谍S去敌方阵地看看是否有坦克,现在问题来了,间谍看到坦克后要怎么通知司令呢(假设跑回来通知太慢了),于是他们想了一个办法,要让司令学会放风筝。

这里创建放风筝这个接口(IS)。并只有一个方法就是拉一下线。

并且间谍S手上永远有一根线,专门用于执行风筝的方法,这个例子里只是拉一下线。

于是司令就实现了放风筝这个接口,这样司令就有了放风筝的本领了(这个本领很强大,一旦有这个本领,就会有一只风筝在你头上飞着,并且线是放你手中的。),这个本领只有一个动作,那就是轻轻拉一下线,当然了这个风筝不拉线也一直是在飞的。

好了,现在司令B派间谍S去敌方阵地,并将S手上的线绑到司令的风筝上(引用传递给S)。

然后S就去敌方阵地了,当S发现有坦克后,于是就用手中的线执行了一下接风筝的方法(动作)。

由于线是绑在司令风筝上的,(引用引向司令这个会放风筝的人),司令就接收到了有坦克的指定,并下达了下一个作战任务(派飞机前去轰炸)。
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

不久另一个司令的间谍死了,决定借这个间谍S用一下,间谍S就说了,要用我当间谍你只要会放风筝就行了,所以,以后只要司令想让间谍去敌方阵地探情报,只要实现放风筝这个接口,并线绑到间谍手上的线上就行了。

》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》

1、服务类

package ex09.ex20.ex01;

public class 间谍 {
	private 放风筝 f;
	
	public 放风筝 getF() {
		return f;
	}

	public void setF(放风筝 f) {
		this.f = f;
	}

	public void 看敌方坦克(){
		System.out.println("间谍:正在要去看敌方坦克。。。");
		System.out.println("间谍:走路中.....");
		System.out.println("间谍:....十分钟后发现有坦克,赶紧拉线通知司令");
		f.拉线();
	}
}

2、调用类,要实现约定的接口


package ex09.ex20.ex01;

public class 司令 implements 放风筝{
	间谍 js = new 间谍();
	
	@Override
	public void 拉线() {
		// TODO Auto-generated method stub
		System.out.println("司令:间谍说有坦克,飞机去轰炸!");
	}
	
	public void 指挥战斗(){
		System.out.println("司令:我正在指挥战斗,决定先派间谍去看敌方有没坦克");
		js.setF(this);
		js.看敌方坦克();
	}
}


3约定的接口

package ex09.ex20.ex01;

public interface 放风筝 {

	public void 拉线();
}


4、测试

package ex09.ex20.ex01;

public class 总指挥 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		司令 sl = new 司令();
		sl.指挥战斗();
	}

}

这里是一个小例子,其它例子都大同小异,有的是将实现直接做为一个匿名类而已。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值