在面向对象的语言中,回调则是通过接口或抽象类来实现的,我们把实现这种接口的类称为回调类,回调类的对象称为回调对象,其处理事件的方法叫做回调方法。(摘自百度百科)

那么通过上面那句话将百度百科中的“回调函数”翻译成JAVA版:回调方法就是一个通过回调对象的引用(java中的引用存的是对象的地址)调用的方法。如果你把

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

下面我们来通过一个小需求来实现回调,需求为:王钢蛋去餐厅打饭,餐厅服务员根据其饭量为其打饭。我们先构思下,首先要有个接口,接口中定义个抽象方法为 饭量(回调接口);其次创建王钢蛋(回调类),让王钢蛋实现这个接口,并想好其饭量(回调方法);最后创建餐厅,餐厅服务员(另一方)接待王钢蛋(回调对 象)并根据其提供的饭量(回调方法)打饭(特定事件,该事件会调用回调方法)。上代码:

/**
 * 顾客,去食堂吃饭有个前提,要告诉服务员其饭量,才会给你盛饭
 * @author coder
 *
 */
interface Client{
    /**
     * 告诉服务员其饭量
     * @return 
     */
    public String appetite();
}

class WangGangDan implements Client{
    @Override
    public String appetite() {
        return "一车米饭";
    }
}
/**
*食堂
*/
class Restaurant{
    /**
     * 打饭方法,前提是客户要告知服务员你的饭量,他会根据你的饭量给你“盛”饭
     * @param client 排队的客户
     * @return
     */
    public String dozenRice(Client client){
        return "盛了"+client.appetite();
    }

}

public class Test1 { //业务处理类,老王去打饭
    public static void main(String[] args) {
        WangGangDan laowang=new WangGangDan(); //王钢蛋以别名laowang去食堂要饭
        Restaurant waiter=new Restaurant(); 
        String dozenRice=waiter.dozenRice(laowang);
        System.out.println(dozenRice); //最后老王“盛了一车米饭”
        //但是通常我们打饭时不会告诉服务员我们叫什么,这样太麻烦了,那么可不可以只告诉服务员
        //饭量多少就给我们打饭呢?按常理来说我们去餐厅也只会要一次饭。
        //匿名内部类多用来实现回调,简便
        String dozenRice1=waiter.dozenRice(new Client(){ 
            @Override
            public String appetite() {
                return "一锅米饭";
            }});
        System.out.println(dozenRice1); 
    }
}

 这里将利用模板方法模式来说明钩子方法是什么,许多设计模式都用到了回调,钩子之类的概念,这些基础点理解了,有些模式也就不那么晦涩难懂了,稍微改写下上面的代码就可以:

/**
 *  模板方法模式:在一个方法中定义一个算法的骨架,而将一些步
 *  骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情
 *  况下,重新定义算法中的某些步骤。
 * 【钩子方法】:原理就是实现为空的方法,在某任务之前、之后、
 *  执行中、报异常后调用的方法(是不是有种熟悉的感觉)。
 *  通常钩子方法是通过抽象类或是本类中的空方法来实现的。
 *
 */
 abstract class Client{
    /**
     * 【模板方法】
     */
    public void templateMethod(){
        before();
        appetite();
        after();
    }
    /**
     * 【钩子方法】在盛饭前(一个空的实现)
     */
     protected void before(){};
    /**
     * 【抽象方法】告诉服务员其饭量
     * @return 饭量
     */
    public abstract void appetite();
    /**
     * 【具体方法】盛饭后
     */
    private void after(){
        //实际项目这里是共有的业务逻辑
        System.out.println("拿筷子,找桌子,开吃...");
    }
}
/**
 *食堂
 */
class Restaurant{
    /**
     * 打饭方法,前提是客户要告知服务员你的饭量,他会根据你的饭量给你“盛”饭
     * @param client 排队的客户
     * @return
     */
    public void dozenRice(Client client){
        client.templateMethod();
    }
}
public class Test1 { //业务处理类,老王去打饭
    public static void main(String[] args) {
        Restaurant waiter=new Restaurant();
        waiter.dozenRice(new Client(){
            @Override
            protected void before() {
                System.out.println("对服务员吹胡子瞪眼!!");
            }
            @Override
            public void appetite() {
                System.out.println("盛了一锅米饭");
            }});
    }
}

 

 

TRANSLATE with x

English

Arabic

Hebrew

Polish

Bulgarian

Hindi

Portuguese

Catalan

Hmong Daw

Romanian

Chinese Simplified

Hungarian

Russian

Chinese Traditional

Indonesian

Slovak

Czech

Italian

Slovenian

Danish

Japanese

Spanish

Dutch

Klingon

Swedish

English

Korean

Thai

Estonian

Latvian

Turkish

Finnish

Lithuanian

Ukrainian

French

Malay

Urdu

German

Maltese

Vietnamese

Greek

Norwegian

Welsh

Haitian Creole

Persian

 

 

TRANSLATE with

COPY THE URL BELOW

Back

EMBED THE SNIPPET BELOW IN YOUR SITE

Enable collaborative features and customize widget: Bing Webmaster Portal

Back

带着疑问去思考,然后串联,进而归纳总结,不断追问自己,进行自我辩证,像侦查嫌疑案件一样看待技术问题,漆黑的街道,你我一起寻找线索,你就是技术界大侦探福尔摩斯