回调函数,就是回头再调用的函数

又遇到了回调函数,此次打算写下来分享一下。javascript

所谓回调函数,或者在面向对象语言里叫回调方法,简单点讲,就是回头在某个时间(事件发生)被调用的函数。java

再详细点:就是一个函数A,做为参数,传入了另外一个函数B,而后被B在某个时间调用。python

这里能够有疑问了,既然是一个函数调用另外一个函数,能够在函数体里面调用啊,为何还要把函数做为参数传到另外一个函数里被调用?况且还有一些语言(好比java)不支持把函数做为参数。android

对的,确实能够在函数体里调用另外一个函数,功能上好像是没差异的,可是这里有一个问题,就是你要调用的这个函数被写死了,也就是说这样函数B只能调用函数A了,这样若是在另外一个情景下,有个与A不一样实现的函数C也须要在B的某个时刻被调用,那怎么办。c++

下面继续说回调函数,在c/c++里,回调函数可使用函数指针做为参数被另外一个函数调用;在c#里,可使用委托,若是是事件方法的话,还有event关键字;在python和javascript里,能够直接把函数当对象传参,这些语言都很好实现回调函数(方法),但是, java呢? 先说点题外话,自从学了C#,就不喜欢java了,曾经一度打算之后再也不用java,但是现实并无那么理想,我如今要作android,因此仍是不能放下java,并且今天遇到这个回调函数的问题,也是从java里遇到的,我我的以为,在这个博客里出现的语言,除了java外,对于回调,均可以既容易,又好理解的实现,可是java,我以为并非那样,否则我也不会来写这篇博客。c#

好了继续说,关于java中的回调方法的实现。这篇博客的重点就是说java的。 在java中,回调方法是用借用接口来实现的,我在网上找到一句话:app

“把实现某一接口的类所建立的对象的引用,赋值给该接口声明的接口变量,那么该接口变量就能够调用被实现的接口的方法”。ide

很绕哈,简单解释下:
有一个接口,接口里有一个方法(这个方法就是要回调的方法):函数

interface CallBackInterface {
    void callBackMethod();
}

咱们知道,接口对象不能直接用,由于里面的方法都没有实现。因此要找个类实现这个接口。
因此如今加一个类,实现这个接口:this

interface CallBackInterface {
    void callBackMethod();
}

class CallBackClass implements CallBackInterface{

    @Override
    public void callBackMethod() {
        System.out.println("hello");
    }
}

好了,最后一步:把实现了接口的类的对象赋值给声明的接口变量(我给写进一个方法里了,而后外面加了个类的壳子):

public class CallBackTest {

    interface CallBackInterface {
        void callBackMethod();
    }

    class CallBackClass implements CallBackInterface {

        @Override
        public void callBackMethod() {
            System.out.println("hello");
        }
    }

    public void showCallBack() {
        CallBackInterface itfs = new CallBackClass();
        itfs.callBackMethod();
    }
}

如今能够调用试试看了:

public class Test {
    public static void main(String[] args) {
        new CallBackTest().showCallBack();
    }
}

没意外的话,会成功输出hello,反正我这边是的.

例子看完了,因此说我作了什么呢? 再详细点说,咱们有一个要在某一个方法里被调用的方法(这个方法就是回调方法), 前面咱们也说了,最好不要直接把想要回调方法作的事直接写在调用方法里, 又由于java里无法把方法当作参数传递,因此咱们只好把这个回调方法放在了接口里(为何不是类?不是抽象类?而是接口?你能够本身去找下抽象类与接口的异同,本身解决这个问题)。有接口的话,就要被类实现,而后,只要是给接口的对象赋予实现类的对象,这个接口的对象就能够调用那个方法了。理解这里的话,有一个重点,就是多态, 这里用到的多态知识就是,接口的对象能够顺利被子类赋值,而且调用子类的重写方法(类也有相似的概念)。

再多说一点,这里任何实现了CallbackInterface接口的类,均可以像下面这样放在new后面(就是赋值):

public class CallBackTest {
    interface CallBackInterface {
        void callBackMethod();
    }

    class CallBackClass implements CallBackInterface {

        @Override
        public void callBackMethod() {
            System.out.println("hello");
        }
    }

    class Controller {
        private CallBackInterface cbitf;
        // 这个boolean只是为了模拟有事件,没啥实用价值
        public boolean somethingHappend;
        // 这里确实能够直接把CallBackClass作参数,并且省掉接口的定义
        // 可是这样作的话,就像是回调函数直接写在了调用函数里同样
        // 不明白的话就好好理解下"约定"和"调用者无论回调函数是怎么实现的"吧
        public Controller(CallBackInterface itfs) {
            somethingHappend = true;
            this.cbitf = itfs;
        }

        public void doSomething() {
            if(somethingHappend) {
                cbitf.callBackMethod();
            }
        }
    }

    public void showCallBack() {
        CallBackClass cbc = new CallBackClass();
        Controller ctrlr = new Controller(cbc);
        ctrlr.doSomething();
        // 其实上面也能够这样写在一行里
        // new Controller(new CallBackClass()).doSomething();
    }
}

最后多说一点,其实这种应用在android里会常常遇到,我就是在学android的时候遇到的。

相关文章
相关标签/搜索