接口回调的理解

    技术2023-06-30  111

    接口回调

    案例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("红烧排骨"); } }

    运行结果:

    Processed: 0.036, SQL: 9