public class B{
//------------调用方式1------------//
//接口对象作用范围全局可用
public CallBack mCallBack;
//(1.1)构造方法赋值
public B(CallBack mmCallBack){
mCallBack = mmCallBack;
}
//(1.2)实例方法赋值
public void setOnCallBack(CallBack mmmCallBack){
mCallBack = mmmCallBack;
}
//(1.3)类方法赋值
public static void setOnCallBackk(CallBack mmmmCallBack){
mCallBack = mmmmCallBack;
}
public void doSomeThingsBB(){
if( mCallBack != null){
mCallBack.onCallBacl("张三");
// do other things.....
}
}
public void doSomeThingsBBbb(){
if( mCallBack != null){
// do other things.....
mCallBack.onCallBack(“李四”);
}
}
//------------调用方式2------------//
//接口对象范围只在此方法中
public void setCallBack(CallBack mCallBack){
mCallBack.onCallBack(“王五”);
}
//接口定义,可在定义为某类的内部,也可单独定义为一个接口java文件
interface CallBack{
public void onCallBack(String name);
}
}
-----------------------------------------------------------------------------------------
实现接口
public class A implements B.CallBack{
public void onCallBack(String name){
System.out.println(name +"A.onCallBacl");
}
public void doSomeThingsAA(){
new B().setCallBack(this);
}
public void doSomeThingsAAaa(){
B.setCallBack(this);
}
}
------------------------------------------------------------------
匿名类
public class A{
setDoSomeThingsA( new B.CallBack(){
onCallBack(String name){
System.out.println(name +"A.onCallBaclxx");
}
});
}
Java是一门面向对象语言,一切皆对象,因此在Java中不存在回调函数这一说法的。由于Java的一切皆对象性质,从而将回调函数这个特性提升到了接口回调。
接口回调是指:可以把实现某一接口的类创建的对象的引用赋给该接口声明的接口变量,那么该接口变量就可以调用被类实现的接口的方法。实际上,当接口变量调用被类实现的接口中的方法时,就是通知相应的对象调用接口的方法,这一过程称为对象功能的接口回调
interface People{
void peopleList();
}
class Student implements People{
public void peopleList(){
System.out.println("I’m a student.");
}
}
class Teacher implements People{
public void peopleList(){
System.out.println("I’m a teacher.");
}
}
public class Example{
public static void main(String args[]){
People a; //声明接口变量
a=new Student(); //实例化,接口变量中存放对象的引用
a.peopleList(); //接口回调
a=new Teacher(); //实例化,接口变量中存放对象的引用
a.peopleList(); //接口回调
}
}
有点抽象?其实直接这么理解就行了:
接口 a =new 实例化接口的对象();
这在设计模式中也是经常用到的,这也是面向对象的一大精髓 -> 面向接口的一个做法,面向接口能够给代码带来更多的解耦,结合设计模式使用能发挥更大作用,面向接口的好处在这里也不多详述了
所谓回调:就是A类中调用B类中的某个方法C,然后B类中反过来调用A类中的方法D,D这个方法就叫回调方法
在Android里边比较不错的例子是
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//TODO:events
}
});
其中,onClick(View view)
就是回调函数,这个流程是这样的:
在当前类中调用了View类的setOnClickListener()
方法,而View类反过来调用了当前类的onClick(View view)
原理就是这样,至于Android源码是怎么回调这个onClick(View view)
的,可以去看看Android的官方源码
(1) 回调接口,首先写好一个接口类
public interface LoadMoreDataAgainListener {
void loadMoreDataAgain(TextView textView, View loadingView);
}
(2) 接着RecyclerView的Adapter写好创建监听器的方法
public void setOnMoreDataLoadAgainListener(LoadMoreDataAgainListener onMoreDataLoadAgainListener) {
mLoadMoreDataAgainListener = onMoreDataLoadAgainListener;
}
(3) 在RecyclerView.ViewHolder中view的监听器:
@OnClick({R.id.loadingIndicatorView, R.id.tv_load_data_again})
public void onClick(View view) {
mLoadMoreDataAgainListener.loadMoreDataAgain(mTvLoadDataAgain, mAvLoadingIndicatorView);
}
(4) 在fragment类中为adapter传递该监听器:
private AddFooterBaseAdapter mAddFooterBaseAdapter;
mAddFooterBaseAdapter.setOnMoreDataLoadAgainListener(new LoadMoreDataAgainListener() {
@Override
public void loadMoreDataAgain(TextView textView, View loadingView) {
textView.setVisibility(View.GONE);
loadingView.setVisibility(View.VISIBLE);
//TODO:加载更多数据
}
});
至此,一个接口实现回调函数的等价功能就实现了
不知道为什么 对于这个java接口回调,我始终不太了解,在网上查询了解的次数也不下五次,哎,有谁知道java接口回调在时候使用它吗?即在什么场景下要用到或是最好是使用java接口回调?哪位知道的请给我留言说明一下好吗?谢谢
接口回调就是:把某接口(接口类A)的实现类(接口实现类B)的实例当作变量传递给某个以此接口为形参的函数(在类C中),利用此参数回调此接口的方法,这就是接口回调
在网上查阅了如下资料,整理如下:
Java Interface ——接口回调解析及实例
通常的认知中java的接口就是用来定义一两个功能函数,其实现类来重写实现这些方法,今天给大家介绍一种很受欢迎且有很大益处的使用方法——接口回调(在Android中大量使用)
互不相识的Tom和Jack,在一次偶然的情况下相遇,Tom觉得Jack很有基情,于是想询问他的名字,并且非常渴望得到他的回应。
-Tom:Hi ! What's name ?
-Jack: I'm Jack!
一个很有基情的小伙子一般都会有这种想法,于是我把这种行为定义为一个接口,使每个有基情的小伙子都会有这种行为。
DemoInter接口(接口类A)
public interface DemoInter {
//inquiry one's name
abstract void name(String string);
}
Tom类(实现接口B)
public class Tom implements DemoInter{
@Override
public void name(String string) {
System.out.println(string);
}
public void inquiry(){
System.out.println("Hi ! What's your name ?");
}
}
(C类)
Jack类里面定义了一个back(回执)的方法,该方法的参数是DemoInter类型,即所有DemoInter的实现类都可以当参数传递进来。而DenoInter接口定义了一个抽象方法name(String string),在back()方法里面调用传递进来的DemoInter实例的name()方法。
public class Jack {
public void back(DemoInter demoInter){
demoInter.name("Hello ! I'm Jack");
}
}
在Tom类编写main()方法
public class Tom implements DemoInter{
@Override
public void name(String string) {
System.out.println(string);
}
public void inquiry(){
System.out.println("Hi ! What's your name ?");
}
public static void main(String[] args) {
Tom tom=new Tom();
Jack jack=new Jack();
tom.inquiry();
jack.back(tom);
}
}
运行结果:
通过以上的小栗子可以看到,接口回调就是,把某接口的实现类的实例当作变量传递给某个以此接口为形参的函数,利用此参数回调此接口的方法,这就是接口回调
资料一:
首先说说什么叫回调函数?
在WINDOWS中,程序员想让系统DLL调用自己编写的一个方法,于是利用DLL当中回调函数(CALLBACK)的接口来编写程序,使它调用,这个就 称为回调。在调用接口时,需要严格的按照定义的参数和方法调用,并且需要处理函数的异步,否则会导致程序的崩溃。
这样的解释似乎还是比较难懂,这里举个简 单的例子:
程序员A写了一段程序(程序a),其中预留有回调函数接口,并封装好了该程序。程序员B要让a调用自己的程序b中的一个方法,于是,他通过a中的接口回调自己b中的方法。目的达到。
在C/C++中,要用回调函数,被掉函数需要告诉调用者自己的指针地址,但在JAVA中没有指针,怎么办?我们可以通过接口(interface)来实现定义回调函数。
假设我是程序员A,以下是我的程序a:
public class Caller {
public MyCallInterface mc;
public void setCallfuc(MyCallInterface mc){
this.mc= mc;
}
public void call(){
this.mc.method();
}
}
我还需要定义一个接口,以便程序员B根据我的定义编写程序实现接口。
public interface MyCallInterface {
public void method();
}
于是,程序员B只需要实现这个接口就能达到回调的目的了:
public class B implements MyCallInterface {
public void method() {
System.out.println("谁来调用我啊。好寂寞!!");
}
public static void main(String args[]) {
Caller call = new Caller();
call.setCallfuc(new B());
call.call();
}
}
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
资料二:
所谓回调,就是客户程序C调用服务程序S中的某个方法a,然后S又在某个时候反过来调用C中的某个方法b,对于C来说,这个b便叫做回调函数。
一般说来,C不会自己调用b,C提供b的目的就是让S来调用它,而且是C不得不提供。由于S并不知道C提供的b叫甚名谁,所以S会约定b的接口规范(函数原型),然后由C提前通过S的一个函数r告诉S自己将要使用b函数,这个过程称为回调函数的注册,r称为注册函数。
下面举个通俗的例子:
某天,我打电话向你请教问题,当然是个难题,:),你一时想不出解决方法,我又不能拿着电话在那里傻等,于是我们约定:等你想出办法后打手机通知我,这样,我就挂掉电话办其它事情去了。过了XX分钟,我的手机响了,你兴高采烈的说问题已经搞定,应该如此这般处理。故事到此结束。
这个例子说明了“异步+回调”的编程模式。其中,你后来打手机告诉我结果便是一个“回调”过程;我的手机号码必须在以前告诉你,这便是注册回调函数;我的手机号码应该有效并且手机能够接收到你的呼叫,这是回调函数必须符合接口规范。
如果你还不太清楚看看这段描述合和代码:
声明一个接口,另外一个类有方法里面有个参数以是这个接口类型的,而后在另外类中实现这个接口(java中多用的是匿名内部类),而且以这个匿名的类生成的对象为参数传到上面提到类中,而后实现回调.......这种用法可以参考java里面常用到的数据库操作所用到的几个接口.....
//声明一个接口
public interface ICallBack {
void postExec();
}
//另外一个类有方法里面有个参数以是这个接口类型的
public class FooBar {
private ICallBack callBack;
public void setCallBack(ICallBack callBack) {
this.callBack = callBack;
}
public void doSth() {
callBack.postExec();
}
}
----------------------------------------
回调的实现
public class Test {
public static void main(String[] args) {
FooBar foo = new FooBar();
foo.setCallBack(new ICallBack() {
public void postExec() {
System.out.println("method executed.");
}
});
foo.doSth();//调用函数
}
}
------------------------------------------------------------------------------------------------------------------------------------------------------------
资料三:一个利用回调函数的经典例子
下面使用java回调函数来实现一个测试函数运行时间的工具类:
如果我们要测试一个类的方法的执行时间,通常我们会这样做:
java 代码
public class TestObject {
/**
* 一个用来被测试的方法,进行了一个比较耗时的循环
*/
public static void testMethod(){
for ( int i= 0 ; i< 100000000 ; i++){
}
}
/**
* 一个简单的测试方法执行时间的方法
*/
public void testTime(){
long begin = System.currentTimeMillis(); //测试起始时间
testMethod(); //测试方法
long end = System.currentTimeMillis(); //测试结束时间
System.out.println("[use time]:" + (end - begin)); //打印使用时间
}
public static void main(String[] args) {
TestObject test=new TestObject();
test.testTime();
}
}
大家看到了testTime()方法,就只有"//测试方法"是需要改变的,下面我们来做一个函数实现相同功能但更灵活:
首先定一个回调接口:
java 代码
public interface CallBack {
//执行回调操作的方法
void execute();
}
然后再写一个工具类:
java 代码
public class Tools {
/**
* 测试函数使用时间,通过定义CallBack接口的execute方法
* @param callBack
*/
public void testTime(CallBack callBack) {
long begin = System.currentTimeMillis(); //测试起始时间
callBack.execute(); ///进行回调操作
long end = System.currentTimeMillis(); //测试结束时间
System.out.println("[use time]:" + (end - begin)); //打印使用时间
}
public static void main(String[] args) {
Tools tool = new Tools();
tool.testTime(new CallBack(){
//定义execute方法
public void execute(){
//这里可以加放一个或多个要测试运行时间的方法
TestObject.testMethod();
}
});
}
}
大家看到,testTime()传入定义callback接口的execute()方法就可以实现回调功能
Java回调函数使用
正常情况下开发人员使用已经定义好的API,这个过程叫Call。但是有时这样不能满足需求,就需要程序员注册自己的程序,然后让事先定义好多API在合适的时候调用注册的方法,这叫CallBack。
“当通常大家说的回调函数一般就是按照别人的定好的接口规范写的,等待别人调用的函数,在C语言中,回调函数通常通过函数指针来传递;在Java中,通常就是编写另外一个类或类库的人规定一个接口,然后你来实现这个接口,然后把这个实现类的一个对象作为参数传给别人的程序,别人的程序必要时就会通过那个接口来调用你编写的函数。”
使用技巧:定一个接口,在接口中声明我们想调用的方法。
在另一个方法中注册刚定义的回调接口
package com.call;
public interface Callback {
public void executeMethod();
}
-----------------------------------------------------
package com.call;
public class Tools {
public void getTime(Callback call) {
long start = System.currentTimeMillis();
call.executeMethod();
long end = System.currentTimeMillis();
System.out.println("cost time=" + (end - start));
}
}
---------------------------------------------
package com.call;
//测试执行方法消耗时间
public class Main {
public static void main(String[] args) {
Tools tool = new Tools();
tool.getTime(new Callback() {
public void executeMethod() {
new Main().testMethod();
}
});
}
public void testMethod() {
for (int i = 0; i < 10000; i++) {
System.out.print("");
}
}
}
资料五:
所谓回调,就是客户程序C调用服务程序S中的某个函数A,然后S又在某个时候反过来调用C中的某个函数B,对于C来说,这个B便叫做回调函数。例如Win32下的窗口过程函数就是一个典型的回调函数。一般说来,C不会自己调用B,C提供B的目的就是让S来调用它,而且是C不得不提供。由于S并不知道C提供的B姓甚名谁,所以S会约定B的接口规范(函数原型),然后由C提前通过S的一个函数R告诉S自己将要使用B函数,这个过程称为回调函数的注册,R称为注册函数。Web Service以及Java的RMI都用到回调机制,可以访问远程服务器程序。
下面举个通俗的例子:
某天,我打电话向你请教问题,当然是个难题,^_^,你一时想不出解决方法,我又不能拿着电话在那里傻等,于是我们约定:等你想出办法后打手机通知我,这样,我就挂掉电话办其它事情去了。过了XX分钟,我的手机响了,你兴高采烈的说问题已经搞定,应该如此这般处理。故事到此结束。这个例子说明了“异步+回调”的编程模式。其中,你后来打手机告诉我结果便是一个“回调”过程;我的手机号码必须在以前告诉你,这便是注册回调函数;我的手机号码应该有效并且手机能够接收到你的呼叫,这是回调函数必须符合接口规范。
通过上面个人感觉到回调更多的应用就是结合异步。比如:Ajax中js通过组件和服务器的异步通信。
例:
程序员A写了一段程序(程序a),其中预留有回调函数接口,并封装好了该程序。程序员B要让a调用自己的程序b中的一个方法,于是,他通过a中的接口回调自己b中的方法。目的达到。在C/C++中,要用回调函数,被掉函数需要告诉调用者自己的指针地址,但在JAVA中没有指针,怎么办?我们可以通过接口(interface)来实现定义回调函数。
假设我是程序员A,以下是我的程序a:
public class Caller
{
public MyCallInterface mc;
public void setCallfuc(MyCallInterface mc)
{
this.mc= mc;
}
public void call(){
this.mc.method();
}
}
我还需要定义一个接口,以便程序员B根据我的定义编写程序实现接口。
public interface MyCallInterface
{
public void method();
}
于是,程序员B只需要实现这个接口就能达到回调的目的了:
public class B implements MyCallInterface
{
public void method()
{
System.out.println("回调");
}
public static void main(String args[])
{
Caller call = new Caller();
call.setCallfuc(new B());
call.call();
}
}