java接口实现回调(观察者模式基础)

标签:

本文出自jvm123.com-java技术分享站:http://jvm123.com/2019/10/java-jie-kou-shi.html

回调是一种双向的调用模式,例如:我们正在写一个类A的a方法,其中调用了B的一个特定的b方法,b在方法执行过程中又要调用一个c方法,这就是回调,c方法被称作回调方法或回调函数。b方法是已有的,而c方法是需要我们自己实现的,也就是原有的方法(b)在执行过程中调用了我们自己实现的代码(c)。

所以可以这样理解:“回调函数也是一个函数或过程,不过它是一个由调用方自己实现,供被调用方使用的特殊函数。”

在js等语言中,c方法(函数)可以被当作参数传给方法b,供它使用。但是在java中,利用接口,就可以实现回调。

java中,按照如下步骤就可以实现回调:

  1. 定义一个接口方法c;
  2. 在实现被调用方法b的时候,调用接口定义的方法;
  3. 在实现调用方法a的时候,调用b方法并把实现了c方法的对象传给b即可。

示例实现如下:

  • 定义一个接口CallBackInterface,其中方法 onFinish 未实现;
package com.yawn.callback;

public interface CallBackInterface {
	void onFinish();
}
  • 在实现被调用方法go的时候,调用接口CallBackInterface 定义的方法 onFinish ;
package com.yawn.callback;

/**
 * B的内部实现也很简单,只需要一个接口类型的成员变量(这个成员变量的具体实现由我们初始化B时指定),
 * 在执行方法完成时调用这个成员变量(接口对象)的onFinish方法即可
 * 
 * @author yawn
 *
 */
public class B {
	CallBackInterface f ;
	public B(CallBackInterface f){
		this.f = f;
	}
	void go(){
		System.out.println("Go go go!");
		if (f != null){
			f.onFinish();
		}
	}
}
  • 在实现方法a的时候,调用b方法并把实现了onFinish方法的对象传给B进行实例化即可。这样在调用b方法过程中,第二步b中调用的接口的方法就会成为其实现类Callback的方法。
package com.yawn.callback;

/**
 * 回调要达到的效果就是在执行完b的go方法之后,再自动调用我们自己实现的onFinish方法
 * A可以是任何一个实现了Finish接口的类,用于存放我们实现的onFinish方法
 * 
 * @author yawn
 *
 */
public class A{
	public static void main(String[] args) {
		B b = new B(new CallBack()); // 初始化B并指定B所要回调的对象(方法)
		b.go();
	}
}

class CallBack implements CallBackInterface {
	@Override
	public void onFinish() {
		System.out.println("finish");
	}
}

这样就可以在调用B的go方法之后又调用我们实现的onFinish方法了。

运行结果
Go go go!
finish

其实在初始化B时不一定要实现一个类A,也可以直接实现接口中的方法:

package com.yawn.callback;

/**
 * 回调要达到的效果就是在执行完b的go方法之后,再自动调用我们自己实现的onClick方法
 * A可以是任何一个实现了Finish接口的类,用于存放我们实现的onFinish方法
 * 
 * @author yawn
 *
 */
public class A {
	public static void main(String[] args) {
		B b = new B(new CallBackInterface() {
			@Override
			public void onFinish() {
				System.out.println("finish");
			}
		});
		b.go();
	}
}

Java中回调的实现也可以这样理解:

在编写B类中被调用方法b的时候,先调用接口的方法占位;在后面实例化B并调用b方法的时候,传入接口的实现即可。这样b方法在执行时调用的接口方法实际上是实现类的方法。

在java中使用接口实现回调,是观察者模式的基础,也是java8中 lambda表达式的基础。在java8中,jdk已经定义了常用的几类接口,我们在实例化b的时候,直接传入接口的实现类即可。如果实现类使用lambda表达式,则书写形式与js中传入函数作为参数很类似。

发表评论