zoukankan      html  css  js  c++  java
  • 回调函数理解

    机制:

    ⑴定义一个回调函数;
    ⑵提供函数实现的一方在初始化的时候,将回调函数的函数指针注册给调用者;
    ⑶当特定的事件或条件发生的时候,调用者使用函数指针调用回调函数对事件进行处理。

    例子:

    一、提供回调的部分

    (1)定义一个回调的监听接口;

    package com.test.callback;
    
    public interface CallListener {
        public void callbackMethod();
    }
    View Code

    (2)定义回调函数Caller;

    package com.test.callback;
    
    public class Caller {
        public CallListener callListener;
        public void setCallListener(CallListener callListener){
            this.callListener = callListener;
        }
        
        public void call(){
            callListener.callbackMethod();
        }
    }
    View Code

    二、调用者部分;调用者实现接口, 实例化调用者的对象传入。

    package com.test.callback;
    public class Client implements CallListener{
        @Override
        public void callbackMethod() {
            System.out.println("实现了回调函数里面的方法");
        }
        /**
         * 测试
         */
        public static void main(String[] args) {
            Caller caller = new Caller();
            caller.setCallListener(new Client());
            caller.call();
        }
    }
    View Code

    ************************************************************************************************************

    接口回调,来自百度百科。

    1概述编辑
    接口回调其本质与上转型是一样的,不同的是:接口回调是用接口句柄来得到并调用实现这个接口的子类的引用;而上转型则是用父类句柄来得到并调用继承此父类的子类的引用。
    2实例编辑
    上面这段话看起来可能有点难以理解,那么下面以一段Java程序来作解释:
    接口:
    public interface Father{
    public void fatherFunc();
    }
    下面三个类都实现了上述接口:
    public class SonA implements Father{
    @override
    public void fatherFunc(){
    ... ...//这里是SonA自己对接口方法的实现
    }
    }
    public class SonB implements Father{
    @override
    public void fatherFunc(){
    ... ...//这里是SonB自己对接口方法的实现
    }
    }
    public class SonC implements Father{
    @override
    public void fatherFunc(){
    ... ...//这里是SonC自己对接口方法的实现
    }
    }
    三个类都实现了共同的接口Father,但是对其中的方法实现可能会有所不同。现在设想一下:在某段事务处理中需要用到接口Father提供的功能(在本例中只有一个方法fatherFunc),可是又无法确定具体是需要哪个子类实现的fatherFunc方法,那么可以直接在事务中声明接口Father的句柄,不用实例化。等到事务运行的时候再自动确定。看下面这段代码:
    public class Deal{
    public void do(Father father){
    father.fatherFunc();//此步骤需要用到接口Father的功能
    ... ...//处理其他事务
    }
    }
    类Deal中用到了接口Father的功能,但是在定义时无法确定是哪一个实现Father的子类,直接使用了接口Father的句柄“Father father”,然后调用father的方法fatherFunc来处理,具体运行是再根据实例化对象调用相应的实现方法:
    public static void main(String[] args){
    Deal deal = new Deal();
    Father fatherA = new SonA();
    Father fatherB = new SonB();
    Father fatherC = new SonC();
    deal.do(fatherA);//调用的是SonA对接口的实现
    deal.do(fatherB);//调用的是SonB对接口的实现
    deal.do(fatherC);//调用的是SonC对接口的实现
    }
    这就达到了具体实现与事务处理的解耦。在类Deal处理事务过程中不需要知道实现接口的子类,这样可以方便的扩充和维护代码,即设计模式的开闭原则(对扩展开放,对修改关闭)。上面的代码中,fatherA、fatherB、fatherC都可以称为接口回调对象,它们虽然被声明为接口Father类型,但是在实例化时却是实现的某个子类。
    上转型和它类似,设计模式就是基于此种“解耦”方法来产生的各种不同应用结构。

  • 相关阅读:
    asp.net导出数据到execl并保存到本地 不需要调用Office组件
    动态创建DataTable,GridView创建多表头,表头跨行或跨列合并,创建计算列及列内容自适应等
    Oracle内置SQL函数收集整理大全
    无比强大的GridView,表头固定,表体有滚动条可滚动
    很不错的asp.net文件上传类c# 搜索文件 移动文件 删除文件等
    【备用】非常不错的ASP操作数据库类,支持多数据库MSSQL,ACCESS,ORACLE,MYSQL等
    Asp.Net读取Execl常见问题收集
    经常用到的交叉表问题,一般用动态SQL能生成动态列
    C# asp.net中常见的字符串处理函数及数字格式化
    比较两个DataTable中不同的记录,且合并两个DataTable的列显示,有图
  • 原文地址:https://www.cnblogs.com/chrono/p/4062817.html
Copyright © 2011-2022 走看看