美文网首页java
java中如何实现"回调函数"

java中如何实现"回调函数"

作者: 赵仝 | 来源:发表于2019-05-12 23:28 被阅读0次

    最近工作需要研究了一会别人写的库,其中充满着各种"回调函数",因此把自己理解给记录下来,存档。
    首先我们来看看回调函数 这个概念的具体由来,百度百科的示义如下:

    回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。

    从上面的这段阐述之中,我们不难发现两点。

    • 函数回调就是将函数指针的地址当作参数传递给另一个函数。
    • 函数回调的用途简单来说就是进行事件的响应或者事件触发。

    既然我们知道回调函数的用途是事件的响应,那么我们就从这里入手。
    假设我们有这样一个场景,一家人坐在一起吃饭,但是我们中国的规矩是,长辈没动筷子,小辈们是不能动的,所以必须等着长辈动筷子这一事件完成之后,小辈们才能开始。
    接下来我们就用回调函数来解决。由于java中没有指针一说,故而也没了*,但是java提供了 接口帮我们实现 回调函数,俗称 接口回调

    首先我们分别创建一个,父亲,儿子,姐姐对象。

    package zt;
    
    /**
     * 接口回调
     */
    public final class App {
        public static void main(String[] args) {
            
        }
    }
    /**
     * 父亲类,里面有个start函数,表示开始动筷子
     */
    class Father{
        private void start(){
            System.out.print("父亲开始动筷子了");
        }
    }
    /**
     * 儿子类,里面有个start函数,表示开始动筷子
     */
    class Son{
        private void start(){
            System.out.print("儿子可以开始动筷子了");
        }
    }
    /**
     * 姐姐类,里面有个start函数,表示开始动筷子
     */
    class Sister{
        private void start(){
            System.out.print("姐姐可以开始动筷子了");
        }
    }
    

    创建好之后,我们要实现,当父亲开始动筷子之后,姐姐和弟弟才能开始动筷子。也就是我们必须将父亲动筷子这个事件传递给姐姐和弟弟对象。

    所以按照逻辑,这个父亲有一个儿子,一个女孩,并且父亲开始动筷子了,他们两个才可以动。代码如下:

    package zt;
    
    /**
     * 接口回调
     */
    public final class App {
        public static void main(String[] args) {
            new Father(new Son(),new Sister()).start();;
        }
    }
    
    interface Start{
        void Fstart(Object obj);
    }
    
    /**
     * 父亲类,里面有个start函数,表示开始动筷子
     */
    class Father{
    
        private Sister sister;
        private Son son;
    
        Father(Son son,Sister sister){
            this.son= son;
            this.sister = sister;
        }
    
        public void start(){
            System.out.println("父亲开始动筷子了");
            son.Fstart("父亲动了筷子");
            sister.Fstart("父亲动了筷子");
        }
    }
    /**
     * 儿子类,里面有个start函数,表示开始动筷子
     */
    class Son implements Start{
        private void start(){
            System.out.println("儿子可以开始动筷子了");
        }
    
        @Override
        public void Fstart(Object obj) {
            if(obj.toString().equals("父亲动了筷子")){
                start();
            }
        }
    }
    /**
     * 姐姐类,里面有个start函数,表示开始动筷子
     */
    class Sister implements Start{
        private void start(){
            System.out.println("姐姐可以开始动筷子了");
        }
    
        @Override
        public void Fstart(Object obj) {
            if(obj.toString().equals("父亲动了筷子")){
                start();
            }
        }
    }
    

    然后运行,结果如下:


    image.png

    这样看起来是不是很灵活,万一生个二胎,再加一个就行了。当然上面的代码并不完美,面向对象的思想告诉我们,我们应该在父亲和儿子,姐姐之间再定义一个Children。代码如下,这样不管生几胎就更省事了:

    package zt;
    
    /**
     * 接口回调
     */
    public final class App {
        public static void main(String[] args) {
            new Father(new Children[] { new Son(), new Sister() }).start();
        }
    }
    
    interface Start {
        void Fstart(Object obj);
    }
    
    /**
     * 父亲类,里面有个start函数,表示开始动筷子
     */
    class Father {
    
        private Children[] childs;
    
        Father(Children[] childs) {
            this.childs = childs;
        }
    
        public void start() {
            System.out.println("父亲开始动筷子了");
            for (Children ch : this.childs) {
                ch.Fstart("父亲动了筷子");
            }
        }
    }
    
    class Children implements Start {
    
        protected void start() {
            System.out.println("孩子们开始动筷子");
        }
    
        @Override
        public void Fstart(Object obj) {
            if (obj.toString().equals("父亲动了筷子")) {
                this.start();
            }
        }
    
    }
    
    /**
     * 儿子类,继承孩子类
     */
    class Son extends Children {
    
        @Override
        protected void start() {
            System.out.println("儿子可以开始动筷子了");
        }
    
    }
    
    /**
     * 姐姐类,继承孩子类
     */
    class Sister extends Children {
        @Override
        protected void start() {
            System.out.println("姐姐可以开始动筷子了");
        }
    }
    
    

    这就是我最近的一些感受,说实话工作快3年了,我最近第一次感受到了面向对象编程的优美。当然也有不好的地方,面向对象把有些事复杂化了。一句话,实践是检验真理的唯一标准,纸上得来终觉浅,绝知此事要躬行。

    相关文章

      网友评论

        本文标题:java中如何实现"回调函数"

        本文链接:https://www.haomeiwen.com/subject/ffwhaqtx.html