案例1:
需求:小明通过迅雷下载视频,下载完成后迅雷通知小明下载完成
实现:
Person类
public class Person { public void download(String url){ System.out.println(this + "准备用迅雷下载数据"); Thunder thunder = new Thunder(); thunder.download(url); } public void downloadComplete(String data){ System.out.println(this + "下载的数据是:" + data); } }Thunder类
public class Thunder { public void download(String url){ System.out.println("开始下载"); System.out.println("下载结束"); String data = "新闻联播全集"; new Person().downloadComplete(data); } }Test类
public class Test { public static void main(String[] args) { Person xiaoMing = new Person(); xiaoMing.download("www.baidu.com"); } }但这样迅雷下完完成后并没有通知小明,那怎么通知呢?return下载的数据?不行,为啥我也不清楚。那或许还有人会想可以new Person().downloadComplete()方法来通知小明,但这样new出来的对象绝不是之前调用download方法的对象,相当于小明下载了一个东西,下载完后迅雷告诉了别人,输出结果如图:
所以小明需要告诉迅雷这个类,你下载完后要调用我的方法告诉我,这时小明调用Thunder中的download方法时可以传一个this对象,Thunder中的download方法新加一个Person参数,下载完毕后通过传递的对象调用downloadComplete即可实现同一个对象,效果如图。
这样虽然解决了这个问题,但是产生了一个新的问题,假设一个Dog类也想通过迅雷下载数据,那它根本调用不了Thunder中的download方法,因为download方法的参数类型是String和Person,显然这是不符合常理的,那应该怎么做的?很简单,Thunder设置一个规范,如果你们想用我的download方法,必须遵循我的规范,而不是Thunder遵循使用者的规范。于是可以设置一个DownloadComplete接口,无论是人还是狗,都必须遵循这个规范,及实现DownloadComplete接口,并重写其downloadComplete方法,调用Thunder类的download方法时依旧传递的是String类型和this,但Thunder中的download方法参数类型分别是String和downloadComplete,这样无论是什么类型,只要实现DownloadComplete就可以调用Thunder的download方法,完整代码如下。
DownloadComplete接口
public interface DownloadComplete { void downloadComplete(String data); }Person类
public class Person implements DownloadComplete { public void download(String url){ System.out.println(this + "准备用迅雷下载数据"); Thunder thunder = new Thunder(); thunder.download(url,this); } @Override public void downloadComplete(String data){ System.out.println(this + "下载的数据是:" + data); } }Dog类
public class Dog implements DownloadComplete { public void download(String url){ System.out.println(this + "准备用迅雷下载数据"); Thunder thunder = new Thunder(); thunder.download(url,this); } @Override public void downloadComplete(String data){ System.out.println(this + "下载的数据是:" + data); } }测试类
public class Test { public static void main(String[] args) { Person xiaoMing = new Person(); xiaoMing.download("www.baidu.com"); System.out.println("=================="); Dog xiaoHa = new Dog(); xiaoHa.download("www.tencent.com"); } }运行结果:
案例2
需求:小明到餐馆吃饭,喊服务员点餐,服务员将顾客的需求告诉厨房。厨房将餐做出来后,由服
务员上给顾客。使⽤回调实现需求。
主要原理于案例1已讲解清楚,这里不再重复
客户需要实现的接口
public interface InformCustomer { void complete(String name); }Customer类
public class Customer implements InformCustomer { public void order(String name){ System.out.println(this+"开始点饭"); Waiter waiter = new Waiter(); waiter.serving(name,this); } @Override public void complete(String name) { System.out.println(this+"开始吃"+name); } }服务员需要实现的接口
public interface InformWaiter { void complete(String name); }Waiter类
public class Waiter implements InformWaiter{ private InformCustomer customer; public void serving(String name,InformCustomer customer){ System.out.println(this+"通知厨师做饭"); this.customer = customer; Cooker cooker = new Cooker(); cooker.cook(name, this); } @Override public void complete(String name) { System.out.println(this+"收到饭了"); customer.complete(name); } }厨师类
public class Cooker { public void cook(String name,InformWaiter waiter){ System.out.println("准备做饭"); System.out.println(name + "做完了"); waiter.complete(name); } }测试类
public class Test { public static void main(String[] args) { Customer xiaoMing = new Customer(); xiaoMing.order("红烧排骨"); } }运行结果: