回调思想和钩子函数的区别
来源:互联网 发布:java链表的实现 编辑:程序博客网 时间:2024/06/05 04:52
浅谈对java callback 以及 “钩子”的理解
1、首先,callback和“钩子”是两个完全不同的概念:
callback是指:由我们自己实现的,但是预留给系统调用的函数,我们自己是没有机会调用的,但是我们知道系统在什么情况下会调用该方法。
“钩子”是指:声明在抽象类中的方法,只有空的或默认的实现,通常应用在模板设计模式中,让子类可以对算法的不同点进行选择或挂钩,要不要挂钩由子类决定。
2、在这里,我主要介绍callback,顺道分析了一下何为“钩子”。那么什么是回调函数呢?我认为,回调函数就是预留给系统调用的函数,而且我们往往知道该函数被调用的时机。这里有两点需要注意:
第一点,我们写回调函数不是给自己调用的,而是准备给系统在将来某一时刻调用的;
第二点,我们应该知道系统在什么情形下会调用我们写的回调函数。
一句话,回调是一种双向调用模式,什么意思呢,就是说,被调用方在被调用时也会调用对方,这就叫回调。“If you call me, i will call back”。
不理解?没关系,先看看这个可以说比较经典的使用回调的方式:
class A实现接口InA ——背景1
class A中包含一个class B的引用b ——背景2
class B有一个参数为InA的方法test(InA a) ——背景3
A的对象a调用B的方法传入自己,test(a) ——这一步相当于you call me
然后b就可以在test方法中调用InA的方法 ——这一步相当于i call you back
3,测试类
4,输出结果:
Making tea...
Boiling water
Dripping Coffee through filter
Pouring into cup
Would you like milk and sugar with your coffee (y/n)?
y
Adding Sugar and Milk
1、首先,callback和“钩子”是两个完全不同的概念:
callback是指:由我们自己实现的,但是预留给系统调用的函数,我们自己是没有机会调用的,但是我们知道系统在什么情况下会调用该方法。
“钩子”是指:声明在抽象类中的方法,只有空的或默认的实现,通常应用在模板设计模式中,让子类可以对算法的不同点进行选择或挂钩,要不要挂钩由子类决定。
2、在这里,我主要介绍callback,顺道分析了一下何为“钩子”。那么什么是回调函数呢?我认为,回调函数就是预留给系统调用的函数,而且我们往往知道该函数被调用的时机。这里有两点需要注意:
第一点,我们写回调函数不是给自己调用的,而是准备给系统在将来某一时刻调用的;
第二点,我们应该知道系统在什么情形下会调用我们写的回调函数。
一句话,回调是一种双向调用模式,什么意思呢,就是说,被调用方在被调用时也会调用对方,这就叫回调。“If you call me, i will call back”。
不理解?没关系,先看看这个可以说比较经典的使用回调的方式:
class A实现接口InA ——背景1
class A中包含一个class B的引用b ——背景2
class B有一个参数为InA的方法test(InA a) ——背景3
A的对象a调用B的方法传入自己,test(a) ——这一步相当于you call me
然后b就可以在test方法中调用InA的方法 ——这一步相当于i call you back
经典代码:
//相当于接口InA public interface BoomWTC{ //获得拉登的决定 public benLaDengDecide(); // 执行轰炸世贸 public void boom(); } //相当于class A public class At$911 implements BoomWTC{//相当于【背景1】 private boolean decide; private TerroristAttack ta;//相当于【背景2】 public At$911(){ Date now=new Date(); SimpleDateFormat myFmt1=new SimpleDateFormat("yy/MM/dd HH:mm"); this.dicede= myFmt.format(dt).equals("01/09/11 09:44"); this.ta=new TerroristAttack(); } //获得拉登的决定 public boolean benLaDengDecide(){ return decide; } // 执行轰炸世贸 public void boom(){ ta.attack(new At$911);//class A调用class B的方法传入自己的对象,相当于【you call me】 } } //相当于class B public class TerroristAttack{ public TerroristAttack(){ } public attack(BoomWTC bmw){//这相当于【背景3】 if(bmw.benLaDengDecide()){//class B在方法中回调class A的方法,相当于【i call you back】 //let's go......... } } }
1,模板类
package com.pattern.template; public abstract class CaffeineBeverageWithHook { void prepareRecipe(){ boilWater(); brew(); pourInCup(); if(customerWantsCondiments()){ addCondiments(); } } abstract void brew(); abstract void addCondiments(); void boilWater(){ System.out.println("Boiling water"); } void pourInCup(){ System.out.println("Pouring into cup"); } boolean customerWantsCondiments(){ return true; } }
package com.pattern.template; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class CoffeeWithHook extends CaffeineBeverageWithHook{ /** * @see com.pattern.template.CaffeineBeverageWithHook#brew() */ @Override void brew() { System.out.println("Dripping Coffee through filter"); } /** * @see com.pattern.template.CaffeineBeverageWithHook#addCondiments() */ @Override void addCondiments() { System.out.println("Adding Sugar and Milk"); } public boolean customerWantsCondiments(){ String answer = getUserInput(); if(answer.toLowerCase().startsWith("y")){ return true; } else{ return false; } } private String getUserInput(){ String answer = null; System.out.println("Would you like milk and sugar with your coffee (y/n)?"); BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); try { answer = in.readLine(); } catch (IOException e) { System.out.println("IO Exception!"); } if(answer == null){ return "no"; } return answer; } }
3,测试类
package com.pattern.template; public class BeverageTestDrive { public static void main(String[] args) { CoffeeWithHook coffeeHook = new CoffeeWithHook(); System.out.println("\nMaking tea..."); coffeeHook.prepareRecipe(); } }
4,输出结果:
Making tea...
Boiling water
Dripping Coffee through filter
Pouring into cup
Would you like milk and sugar with your coffee (y/n)?
y
Adding Sugar and Milk
0 0
- 回调思想和钩子函数的区别
- 钩子函数和回调函数的区别
- 回调函数和钩子函数的区别
- 钩子函数与回调函数的区别
- 修改按键的回调钩子函数
- 线程专用钩子和全局钩子的区别
- 钩子和回调
- 关于回调函数和钩子函数基础知识的整理
- 关于回调函数和钩子函数基础知识的整理
- 关于回调函数和钩子函数基础知识的整理
- 关于回调函数和钩子函数基础知识的整理
- 关于回调函数和钩子函数基础知识的整理
- 关于回调函数和钩子函数基础知识的整理
- 关于回调函数和钩子函数基础知识的整理
- Vue2.X的路由和钩子函数
- vue js 的生命周期和钩子函数
- vue生命周期和钩子函数的理解
- PreTranslateMessage和钩子区别
- Ajax学习(3)数据格式提要
- NOIP 2009 最优贸易
- 82. Remove Duplicates from Sorted List II
- uva673 Parentheses Balance
- boost::io_service 的使用 & 如何检查网络通讯正常?心跳包机制 or Detection of Half-Open (Dropped) Connections
- 回调思想和钩子函数的区别
- 计算Windows下目录大小
- 2014华为上机题C++编程
- Android-Universal-Image-Loader 属性设置
- Android 开发测试环境切换工具
- SLF4J versions 1.4.0 and later requires log4j 1.2.12 or later
- hibernate @Entity @Table 实体类中不可以随便添加与表字段不对应的get方法,如增加请加注解 @Transient
- Ddr2,ddr3,ddr4内存条的读写速率
- Java 单例模式