通过前面两篇文章,我们学习了Kotlin的基本知识,并知道如何配置工程,本文将接着介绍Java没有的而Kotlin实现了的有趣的特性。记住当你对Kotlin语言有任何疑问时,请参考官方指南。该指南组织的很好,而且容易理解,本文将不会介绍语言的基本知识。

扩展函数

Kotlin的扩展函数功能使得我们可以为现有的类添加新的函数,而不用修改原来的类。例如,我们可以为一个activity添加一个新函数,用于显示一个toast:

fun Activity.toast(message: CharSequence, duration: Int = Toast.LENGTH_SHORT){

Toast.makeText(this, message, duration)
.show()
}

我们可以在任何地方声明这个函数(例如在一个utils文件中),然后像使用普通函数一样在这个activity中使用它:

override fun onCreate(savedInstanceState: Bundle?) {
super<BaseActivity>.onCreate(savedInstanceState)

toast("This is onCreate!!")

}

声明一个扩展函数很简单,只需要在函数名之前添加指定的类名即可。在调用时,该函数会以导入的方式添加到这个类中。

扩展函数帮助我们简化代码,并极大的利用封闭的类。不过我们要小心并且不过度使用它。使用扩展函数的一个结果是它通常用于替代工具类。工具函数是静态的而且不能被mocked,因此过度使用工具函数通常是我们懒得创建托管类的结果。

下面是另一个有趣的例子,用于解释另一个有趣的概念:具体化(reified)类型。

inline public fun <reified T : Activity> Activity.navigate(id: String) {

val intent = Intent(this, javaClass<T>())

 intent.putExtra("id", id)

 startActivity(intent)

}

内联函数可以使用具体化(reified)类型,这意味着我们可以在一个函数内部通过类型来恢复一个类,而不是将类的类型作为一个参数传入。

內联函数和普通函数有一点区别。內联函数在编译期间会进行代码替换,而不是真的进行函数调用。在某些情况下可以简化问题。例如,如果我们有一个函数会作用参数进行传递,普通函数会在内部创建一个包含这个函数的对象;而內联函数将会在函数被调用的地方使用代码直接替换函数调用,因此不需要创建一个内部对象。

navigate<DetailActivity>("2")

使用reified类型,我们可以在一个函数内部创建一个intent,并使用扩展函数,这样我们可以直接调用startActivity()。

可选参数和默认值

借助于参数和构造函数的默认值,你将不再需要进行函数重载了。一个函数声明就可以满足你所有的需求。让我们回到toast的例子:

fun Activity.toast(message: CharSequence, duration: Int = Toast.LENGTH_SHORT){

Toast.makeText(this, message, duration)

}

第二个参数表示toast的显示持续时间,这是一个可选参数,但没有显式指定时,将使用默认的Toast.LENGTH_SHORT。因此,你有两种方式调用这个函数:

toast("Short Toast!!")
toast("Long Toast!!", Toast.LENGTH_LONG)

回到前面第二个例子,我们可能想要增加几个参数来支持lollipop动画:

inline public fun <reified T : Activity> Activity.navigate(

 id: String,

sharedView: View? = null,

 transitionName: String? = null) {


...

现在我们有两种方式调用同一个函数:

navigate<DetailActivity>("2")
navigate<DetailActivity>("2", sharedView, TRANSITION_NAME)

甚至还有第三种方式,在这种情况下意义不大,但有助于帮助我们理解另一个概念:我们可以使用参数名字来决定哪个参数会被调用:

navigate<DetailActivity>(id = "2", transitionName = TRANSITION_NAME)

可选参数也可以被用在默认构造函数中,因此,你可以只声明一个构造函数,但会得到很多重载。自定义views是一个特殊例子,在Java中它们需要多于一个构造函数以便正确的运行,我会在下一篇文章中进行介绍。

总结

使用扩展函数以及可选参数和默认值,我们可以节省很多代码,甚至完成在Java中无法做到的事情。Kotlin真的更具表达性而且简洁。下一篇文章将会介绍Kotlin的Android扩展,它使得我们可以在activities中自动注入views,同时也会介绍使用Kotlin创建自定义views。

请记得查看实际运行我们的Demo例子,实践出真知。

使用Kotlin开发Android应用(III):扩展函数和默认值的更多相关文章

  1. 让你的代码量减少3倍!使用kotlin开发Android(二) --秘笈!扩展函数

    本文承接上一篇文章:让你的代码量减少3倍!使用kotlin开发Android(一) 创建Kotlin工程 本文同步自博主的私人博客wing的地方酒馆 上一节说到,kotlin可以省去getter,se ...

  2. 用Kotlin开发Android应用(IV):定制视图和Android扩展

    原文标题:Kotlin for Android (IV): Custom Views and Android Extensions 原文链接:http://antonioleiva.com/kotli ...

  3. 用Kotlin开发Android应用(I):介绍

    关于Kotlin,网上已有一些介绍的文章,包括Antonio Leiva的这组blog翻译稿.不过,我还是想跟进它们.翻译它们,以锻炼自己的英文翻译.各位高手发现问题,请及时“拍砖”. 原文题目:Ko ...

  4. 使用Kotlin开发Android应用(I):简单介绍

    使用Kotlin开发Android应用(I):简单介绍 @author ASCE1885的 Github 简书 微博 CSDN 原文链接 Kotlin是一门基于JVM的编程语言.它正成长为Androi ...

  5. 使用Kotlin开发Android应用(IV):自定义视图和Android扩展

    在读完扩展函数和默认值这篇文章之后,那么接下来要介绍什么呢?在本系列第一篇文章中我们说过,Kotlin使得Android开发更加简单,本文我们将进一步作介绍. 自定义视图 你应该还记得,在说到Kotl ...

  6. 用Kotlin开发Android应用(II):创建新项目

    这是关于Kotlin的第二篇.各位高手发现问题,请继续“拍砖”. 原文标题:Kotlin for Android(II): Create a new project 原文链接:http://anton ...

  7. 让你的代码量减少3倍!使用kotlin开发Android(一)

    让你的代码量减少3倍!使用kotlin开发Android(一) 创建Kotlin工程 本文同步自博主的私人博客:wing的地方酒馆 写在前面 使用kotlin开发android已经两周多了.得到的好处 ...

  8. 使用Kotlin开发Android应用 - 环境搭建 (1)

    一. 在Android Studio上安装Kotlin插件 按快捷键Command+, -> 在Preferences界面找到Plugins -> 点击Browse repositorie ...

  9. 使用Kotlin开发Android应用(II):创建新工程

    在基本了解什么是Kotlin以及Kotlin可以做什么之后,接下来就到了配置Android Studio并使用Kotlin开发Android apps的时候了.首次配置Android Studio需要 ...

  10. 使用Kotlin开发Android

    查看我的所有开源项目[开源实验室] 欢迎增加我的QQ群:[201055521],本博客client源代码下载[请点击] 摘要 我首先声明我并没有使用Kotlin非常长时间,我差点儿是在学习的同一时候写 ...

随机推荐

  1. CAN总线过滤规则

    奇怪的设计 If (AFMR & Message_ID) == (AFMR & AFIR) then Capture Message AFIR 1 接收 AFMR 0 接收 设置某接收 ...

  2. Xilinx 7系列例化MIG IP core DDR3读写

    昨晚找了一下,发现DDR3读写在工程上多是通过例化MIG,调用生成IPcore的HDL Functional Model.我说嘛,自己哪能写出那么繁琐的,不过DDR读写数据可以用到状态机,后期再添砖加 ...

  3. mybatis 使用注解实现多参数传递

    若映射器中的方法只有一个参数,则在对应的SQL语句中,可以采用#{参数名}的方式来引用此参数,以前的例子多属于此类.但这种方法却不适用于需要传递多个参数的情况,今天就来介绍如何使用注解传递多个参数 一 ...

  4. Unix 环境高级编程

    UNIX 环境高级编程 本书描述了UNIX系统的程序设计接口--系统调用接口和标准C库提供的很多函数. 与大多数操作系统一样,Unix为程序员运行提供了大量的服务--打开文件,读文件,启动一个新程序, ...

  5. Java并发编程(三)概念介绍

    在构建稳健的并发程序时,必须正确使用线程和锁.但是这终归只是一些机制.要编写线程安全的代码,其核心在于要对状态访问操作进行管理,特别是对共享的(Shared)和可变的(Mutable)状态的访问. 对 ...

  6. php 循环简写

    <?php class a{ public function news($news){ $articles = array(); foreach ($news as $key => $va ...

  7. C++标准库之tuple

    构造 构造函数 tuple的构造函数很普通,没啥说的. default (1) constexpr tuple();默认构造函数 copy / move (2) tuple (const tuple& ...

  8. [前端开发] 未来趋势“无后端”的web应用开发模式

    最近看到前端趋势2013大会上的一篇文章,题目是<各位快看,不用后端>,觉得有点意思,恰好近期的一次讨论及半年前的一次开发实践也涉及到这种模式,简单谈谈我的想法. 不得不说,文章的题目确实 ...

  9. POJ 3480 &amp; HDU 1907 John(尼姆博弈变形)

    题目链接: PKU:http://poj.org/problem? id=3480 HDU:http://acm.hdu.edu.cn/showproblem.php? pid=1907 Descri ...

  10. echarts(3.0)的基本使用(标签式导入)

    function loadRainFallCharts(msg) { var obj = {}; obj.x = []; obj.y = []; obj.line = []; var accumula ...