zoukankan      html  css  js  c++  java
  • 使用Kotlin开发Android应用(III):扩展函数和默认值

    通过前面两篇文章,我们学习了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例子,实践出真知。

  • 相关阅读:
    《将博客搬至CSDN》
    2015-05-01 至 2015-07-30错误总结
    2015-01-01至2015-04-30错误积累
    2015-07-30 至 2016-03-16错误Note
    2014-11-21错误总结
    Spring 和 SpringMVC 的区别
    spring 容器加载
    Spring注解
    自定义拦截器
    Js闭包
  • 原文地址:https://www.cnblogs.com/simadi/p/6688427.html
Copyright © 2011-2022 走看看