Kotlin实现多函数接口的简化调用

对于一个声明了多个方法的接口,我们使用的时候有时仅仅关注于几个关键方法,并不需要实现所有的。可是由于接口调用的语法限制,使得我们不得不在代码中也显示声明实现了那些我们不关心的方法。在Java中也有简化接口调用的方式,比如安卓中ViewPager监听页面切换时的接口PageChangeListener,官方提供了简单类: ViewPager.SimpleOnPageChangeListener来简化调用。

对于Kotlin来说,可以类似使用java的方式,来实现多函数接口的简化调用,只是要用到object关键字且代码仍会较多。这里,由于Kotlin的语法更为灵活,去实现这种调用应该有其特色的方式,使得代码更少,且更加具有张力。

来个小例子,先简单介绍类似java实现多函数接口的简化调用,一是展示什么是简化接口调用,二是做对比。这里得例子都用kotlin写的。

1.声明接口CallBack 和调用类Worker

interface CallBack { fun onSuccess(str: String) fun onFailure(code: Int) } class Worker { var callback: CallBack? = null fun done(str: String) { callback?.onSuccess(str) } fun fail(code: Int) { callback?.onFailure(code) } fun setCallBack(lis: CallBack) { callback = lis; } }

2.直接调用接口,使用了object关键字 ,此时假设不关心success方法,但必须显示声明。

Worker().apply { setCallBack(object : CallBack { override fun onSuccess(str: String) { } override fun onFailure(code: Int) { toast("$code") } }) }.fail(110) //结果:吐司:110

3.Java风格简化调用,声明简化类SimCallBack

public class SimCallBack implements CallBack{ @Override public void onSuccess(@NotNull String str) { } @Override public void onFailure(int code) { } }

4.Java风格简化调用的展示,不关心的onSuccess不用再显示声明

Worker().apply { setCallBack(object : SimCallBack() { override fun onFailure(code: Int) { super.onFailure(code) toast("$code") } }) }.fail(110)

上述带着浓浓java味道的调用,不仅代码风格比较混杂,而且代码显得冗余。重点来了,Kotlin怎么去克服上面两点呢。看例子。

1.还是CallBack接口,不过其简化类需要用Kotlin风格来做:

class SimpleCallBack : CallBack{ private var _OnSucess: ((str: String) -> Unit)? = null fun success(listener: (str: String) -> Unit) { _OnSucess = listener } override fun onSuccess(str: String) { _OnSucess?.invoke(str) } private var _OnFailure: ((code: Int) -> Unit)? = null override fun onFailure(code: Int) { _OnFailure?.invoke(code) } fun fail(listener: (code: Int) -> Unit) { _OnFailure = listener } }

声明了两个函数类型变量 _OnSucess和 _OnFailure,作用就是内部将原来的大接口CallBack分解。然后声明了对应的方法success和fail,目的是给变量小接口赋值。接着就是原接口方法的处理,比如原接口方法onSuccess(str: String)的操作 _OnSucess?.invoke(str),目的是实现接口回调结果的转移。做这些,目的就是为以后的简化调用做准备。

2.调用类Worker 也是要进行处理一下的,代码基本同原来的那些,只是增加了以下方法。注意,若不是为了兼容java方式,原setCallBack可以不再声明,直接赋值就好,由此,新增方法可以看做是原setCallBack方法的替换。

fun setCallBacker(listener: SimpleCallBack.() -> Unit) { var ca = SimpleCallBack() ca.listener() setCallBack(ca) }

注意名称。本方法接受一个函数参数,方法的作用是内部生成一个简化接口对象SimpleCallBack,然后再让调用类注册到接口。然后执行传进来的函数参数,为什么要这样呢,是为了使用kotlin语法中灵活的闭包{}。另外,配上强大的函数扩展语法,不改变原有类,增加个这种方法还是比较容易的。

3.最后看看调用方式吧:

Worker().apply { setCallBacker { success { toast(it) } fail { }//若不需要,可以不显示声明 } }.done("完成") //结果:吐司:完成

最后结果可以看出,当调用多函数接口CallBack时,并不需要再声明接口,而是直接在闭包里声明想要使用的方法,然后在对应的方法闭包里执行操作即可。风格完全是kotlin,且使用特别简便。

分享结束,希望对读者有所帮助。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

时间: 2024-08-03 16:16:59

Kotlin实现多函数接口的简化调用的相关文章

Flex扩展HTTPService简化调用接口定义

Flex提供MXML来描述一个HTTPService,看上可以简化开发人员的工作,但实际上这种描 述HTTPService的方式很容易产生重复代码导致代码不好维护和扩展.数据交互接口唯一定义 对系统的维护非常有利,但基于AS定义HTTPService也是一件烦琐的事情:那如何做才能够达 到方便地定义接口呢. 接口定义 以下是定义一个登陆的 HTTPService public class ILogin extends HttpBase { public function ILogin(metho

c++-C与C++的区别仅在于OPP吗?linux 编程C++是不是么有C++接口,只是调用C接口吗?

问题描述 C与C++的区别仅在于OPP吗?linux 编程C++是不是么有C++接口,只是调用C接口吗? C与C++的区别仅在于OPP吗?linux 编程C++是不是么有C++接口,只是调用C接口吗? 解决方案 C和C++最大的区别当然是C++支持OOP,但是它们也有一些细节上的不同.比如C++支持模板.引用.命名空间等,C++ 11/14更是增加了Lambda表达式.类型推断.自动指针等等. 解决方案二: 不是的呀,c++库是跨平台的 解决方案三: C调用C++接口c++中调用c接口的问题Li

c# 4 0-知道 ibm MQ接口不知道怎么调用读取数据?

问题描述 知道 ibm MQ接口不知道怎么调用读取数据? 知道 ibm MQ接口不知道怎么调用读取数据? IP:外网调试请用101.86.12.34 Port:外网调试请用4443 队列:QL_XIAN_d 解决方案 谁知道用C#怎么调用?帮帮我..

接口实现类调用接口的全局常量?

问题描述 我们都知道接口中的全局变量必须是public static final的常量,我们可以通过接口名来调用它,也可以用该接口的实现类来调用该常量,但是eclipse中好像不赞成这样调用,不知道接口实现类调用接口的常量与直接用接口名调用该常量有何区别?为什么eclipse中不赞成这样使用? 解决方案 因为接口是可以多实现 的,比如 A接口有个常量NUMBER = 1000,B接口也有常量NUMBER = 1000.类C实现这两接口,如果直接引用NUMBER是不行的.再一个就是扩展性.如:C实

关于http接口防止非法调用的设计方案

关于http接口防止非法调用的设计方案   假设有个http接口: 如 http://www.a.com/getBlog.jsp?uid=12  其他系统要调用这个接口取数据: 如果不做安全处理,任何系统只要知道接口地址和参数即可调用.很可能造成非法调用,造成安全问题. . 为了安全,可以考虑如下方案: 接口调用时增加一个校验参数:如 mcheck=xxxxxx http://www.a.com/getBlog.jsp?uid=12&mcheck=xxxxxx 校验参数生成规则 假设如下:  

表单控件续(1)——应用接口来简化和分散代码

上次有点仓促,有几个地方没有明确. 1.两篇随笔可以合在一起看能自己"跑"的表单控件,思路,雏形,源码.vs2005版本 我写项目的步骤.抛砖引玉.   后者是整个流程,前者是其中的一个步骤,是一个简单的思路说明,其中前三段代码都是表单控件里面的. 2.我要写的是一个表单控件,b/s结构里面的控件.虽然内部会有点复杂,但是编译成dll后,调用就会很方便了. 上一篇里的表单控件有很多需要完善的地方,这里先说一下扩展性.       扩展呢就是说可以比较方便的添加更多的子控件,而现在的表单

调用接口参数问题-调用接口,接口那边接收的参数是null

问题描述 调用接口,接口那边接收的参数是null "GSCKDJ"是接口里面的方法,那三个是传递的参数,不知道是怎么设置传递的参数的??在接口那边输出参数全是null,求解!

接口-RMI远程调用,一服务端和客户端一定要在一个工程里么

问题描述 RMI远程调用,一服务端和客户端一定要在一个工程里么 小弟初学RMI的知识,网上说的也不明白,我自己做了一个helloword测试,我不太明白的是 ,服务端和客户端一定要在一个工程下么?如果一定在一个工程下,那还算什么远程调用啊? 可是我在服务端有一个接口:IHello,成功绑定到8888端口之后,我新建客户端工程,在 IHello iHello = Naming.lookup("rmi://localhost:8888/IHello"); 在写这句话的时候,MyEclips

接口-php怎么调用wcf服务,调用参数是对象参数。

问题描述 php怎么调用wcf服务,调用参数是对象参数. .net做的wcf接口,部署IIS上访问是可以的如图: 我用php soap调用测试,是否能通,也是可以的: <?php header('Content-Type: text/plain'); $client = new SoapClient('http://testu.sh.jinri.com/Flight.User.SOA/SuggestService.svc?wsdl'); echo ' '; echo "提供的方法n&quo