用Kotlin开发Android应用(III):扩展函数和默认值

这是关于Kotlin的第三篇。

 

原文标题:Kotlin for Android (III): Extension functions and default values

原文链接:http://antonioleiva.com/kotlin-android-extension-functions/

原文作者:Antonio Leiva(http://antonioleiva.com/about/

原文发布:2015-04-06

 

 

在你了解Kotlin的基本知识怎样配置你的项目后,现在我们可以聊聊Kotlin能够为我们做到那些令人关注的事情,而这些Java做不到。记住,如果你对Koklin语言有什么疑问,你可以查阅官方文档。官方文档组织得非常好,并且容易理解。这样在文章中,我将不涵盖基本语言的内容。

 

扩展函数

 

Kotlin扩展函数允许我们在不改变已有类的情况下,为类添加新的函数。例如,我们能够为Activity中添加新的方法,让我们以更简单术语显示toast:

 

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

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

 

我们可以在任何地方(如一个utils文件中)声明这个函数,在我们的Activity中将它作为普通方法来使用:

 

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

3     toast("This is onCreate!!")

4 }

 

声明扩展函数只需简单地在函数名前加上类名就可以了。在调用处,该函数被导入到类中。

 

这能够帮助我们简化代码、让封闭类超出其限制。但是,我们必须小心,不能过度使用它们。最终,这些函数通常将替代util类。Util方法是静态且不能被模拟(mock),所以过度使用通常表示我太懒,不愿创建委托类。

 

这是另一个有趣的例子,我来解释另一个有趣的概念:具体化类型(reified type)。

 

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

2     val intent = Intent(this, javaClass<T>())
3 
    intent.putExtra("id", id)
4 
    startActivity(intent)

5 }

 

内联函数能用具体化类型,这意味着我们可以用函数内部的类型恢复类,而不是以自变量传递类类型。

 

内联函数与普通函数有点不同。在编译期间,内联函数会进行代码替换,而不是实际调用函数。这可以使一些问题得以简化。例如,如果有一个自变量是函数,普通函数将在其内部创建一个包含那函数的对象。而内联函数则在调用它的地方用其代码来替换,所以为此不要求内部对象。

 

1 navigate<DetailActivity>("2")

 

用具体化类型,我们能够在函数内部创建intent;用扩展函数,我们能够直接调用startActivity()

 

可选参数和默认值

 

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

 

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

2     Toast.makeText(this, message, duration)

3 }

 

第二个自变量表示toast显示持续时间。它是可选参数,如果没有特别说明,它将用Toast.LENGTH_SHORT。现在你有两种方法去调用这个函数:

 

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

 

对于第二个例子,我们可能要为lollipop过渡添加自变量:

 

1 inline public fun <reified T : Activity> Activity.navigate(
2 
        id: String,
3         sharedView: View? = null,
4 
        transitionName: String? = null) {
5     ...
6 
}

 

现在我们有两种不同的方法来调用同一个函数:

 

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

 

甚至有第三种方法,但是在这种情况下没有太多的意义,但是可以帮助我们理解另一个概念:我们可以用参数的名称来决定我们要调用哪个参数:

 

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

 

可选参数也可以用于默认的构造函数,这样你就能在一条声明中获得多种重载。自定义视图是一个特殊的例子,因为在Java中,它们需要多个构造函数才能正常工作。这将在下篇文章中说明。

 

总结

 

用这两个概念,我们可以节省许多代码,甚至可以实现在Java中不可能实现的事。Kotlin极具表达能力且简洁。下篇文章将说明Kotlin Android扩展,可以让我们在Activity中自动地注入视图,以及在Kotlin中怎样产生自定义视图。

 

记住去查看例子的代码,看看它的实际应用。

 

前一篇:http://www.cnblogs.com/figozhg/p/4983919.html

 

posted @ 2015-11-25 22:21  figozhg  阅读(2794)  评论(0编辑  收藏  举报