初始Kotlin<下>

来源:互联网 发布:简易机器人编程语言 编辑:程序博客网 时间:2024/06/17 21:38

上一篇《初始Kotlin<上>》

在上一篇文章中介绍了Kotlin的一些基本语法,包括变量、常量的定义、控制循环语句、函数的定义及使用、类的定义、方法和属性、继承、数据类、枚举类、异常处理、类型检查和转换等部分的内容。这这篇文章中记录一下接口、泛型以及扩展的部分内容。
接上篇继续

8、接口:

在java语言中也有接口的定义,和kotlin中相比相差不大。那什么是接口呢?
接口就是对方法或者属性的实现标准。这样说可能有点抽象。举个例子:每一个自然人呢都有一个名字,然后现在有一个歪果仁想要加入中国的国籍,想要以后在中国发展。那咱们定义一个人(Person)的类,然后再定义一个歪果仁(ForigChinese)的类去继承人(Person)的类。
这时候这个歪果仁要加入中国的国籍,那怎么办呢,我们不能在Person类中添加加入中国国籍的方法。所以我们去写一个接口,定义一个加入中国国籍的方法,让想要加入中国国籍的歪果仁去实现这个方法。这样,这个歪果仁的实例就可以去调用加入中国国籍的方法了。
具体的咱们来看下边的代码:
首先定义一个Person类,因为这个类需要被其他的类继承,所以使用open关键字来修饰

   open class Person {        var name = ""    }

然后去定义一个可以生存的接口:

    interface Livable {        //接口中的属性和方法不能初始化        var hasSkill: Boolean//接口中的属性        fun addChina() //接口中的方法        //接口中的方法可以有默认实现,通常指该方法是固定不变的        fun SpeakChinese() {            LogUtils.Loge("接口中的默认方法:我可以说中文")        }    }

然后定义一个可以在中国生存的接口:

    interface ChinaLivable {        //接口中的属性不可初始化        val hasJobOffer: Boolean        //接口中可以有get方法,通常用于增加一个常量属性        val visaCatagory: String            get() = "工作offer"        //接口中的属性        var city: String    }

然后去定义一个歪果仁的类继承Person类,并且实现生存接口和在中国生存的接口:

    class ForigChinese : Person(), Livable, ChinaLivable {        override var hasJobOffer: Boolean = true        override var city: String = "北京"        override var hasSkill: Boolean = true        override fun addChina() {            LogUtils.Loge("我叫${name}我要加入中国国籍")        }    }

这时候,这个歪果仁就有了生存的能力,并且有了在总过生存的能力。所以他就能加入中国国籍了。

        var mForigChinese = ForigChinese()        mForigChinese.name = "小米"        mForigChinese.city = "北京"        mForigChinese.hasJobOffer = true        mForigChinese.hasSkill = true        mForigChinese.addChina()        mForigChinese.SpeakChinese()        LogUtils.Loge("接口名称:" + mForigChinese.name)        LogUtils.Loge("接口城市:" + mForigChinese.city)        LogUtils.Loge("接口是否有工作:" + mForigChinese.hasJobOffer)        LogUtils.Loge("接口是否有生存技能:" + mForigChinese.hasSkill)

然后看一下Log:

11-16 15:49:22.968 4994-4994/com.example.lql.kotlindemo E/###: 我叫小米我要加入中国国籍###11-16 15:49:22.968 4994-4994/com.example.lql.kotlindemo E/###: 接口中的默认方法:我可以说中文###11-16 15:49:22.968 4994-4994/com.example.lql.kotlindemo E/###: 接口名称:小米###11-16 15:49:22.968 4994-4994/com.example.lql.kotlindemo E/###: 接口城市:北京###11-16 15:49:22.968 4994-4994/com.example.lql.kotlindemo E/###: 接口是否有工作:true###11-16 15:49:22.968 4994-4994/com.example.lql.kotlindemo E/###: 接口是否有生存技能:true###

我们发现我们给歪果仁(ForigChinese )类添加了两个能力,一个是生存的能力,一个是在中国生存的能力,但是ForigChinese类本身看起来并没有复杂。所以,接口可以给 类附加能力,并且让类看起来很简洁。
还有一点,这个能力并没有在父类中去实现,所以通过接口的方法来实现某些功能,是可以选择的,如果我不想要在中国生存的能力,就可以不实现这个接口就好了。使用起来很方便。

9、泛型:

泛型就是让一个函数或者类能更加通用,首先咱们看一下系统给提供的一下泛型的方法。

//定义一个Int类型的数组var intList = arrayOf(1, 2, 3, 4, 5, 6, 7, 10)//定义一个String类型的数组var stringList = arrayOf("1","2","3","4","5","6","7","9")

我们发现arrayOf方法,我们既可以传Int类型的参数进去,也可以传String类型的参数进去。这就是泛型方法的体现。
在我们定义方法或者类的时候,有时候也要考虑这个因素进去,我们写了一个工具类,能不能传递不同类型的传输进去呢?这可以让方法在更多的情境下使用。

9.1基本泛型

然后我们来看一下泛型在Kotlin中的写法:

    //定义一个泛型函数: <T> T表示一个占位符    fun <T> showText(para: T) {        LogUtils.Loge("泛型入参:" + para.toString())    }

然后调用这个方法:

 showText(3)showText("123")

Log:

11-16 16:02:29.258 4994-4994/com.example.lql.kotlindemo E/###: 泛型入参:3###11-16 16:02:29.258 4994-4994/com.example.lql.kotlindemo E/###: 泛型入参:123###

我们可以看到对与一个方法showText()传递了两种不同类型的参数进去。

9.2约束泛型:

现在我们有一个数组

arrayOf(1, 2, 3, 4, 5, 6, 7, 10, 11)

我们相对这个数组求和,这个时候我们参数都是Int类型的,我们可以直接调用.sum()方法去求和。
然后咱们把数组改一下

arrayOf(1, 2, 3, 4, 5, 6, 7, 10, 11.11)

这样,里边多了一个double类型的元素。这时候就没办法调用.sum()方法了。然后我们使用约束泛型去实现一个求和方法:

 //下边就是泛型约束:<泛型占位符: 类型>  把泛型约束在Number类型中    fun <T : Number> sum2(vararg number: T): Double {        return number.sumByDouble { it.toDouble() }    }

通过上边的注释,大家应该能看懂这个约束泛型的意思。就不再解释了。

9.3多重约束泛型:

写法就是把多个约束用where修饰,中间使用“ , ”隔开,写在函数体之前。
例子:把数组中大于某个元素的部分都取出来并升序排列

    //Comparable 可比较的,大于、小于、等于    fun <T> biggerPart(list: Array<T>, threhold: T): List<T>  where T : Number, T : Comparable<T> {        return list.filter { it >= threhold }.sorted()    }

来看一下试用方法:

//多重约束        val biggerPart = biggerPart(arrayOf(99, 1, 2, -2, 88, 1024, 888), 3)        for (i in biggerPart) {            LogUtils.Loge("多重约束:${i}")        }

Log:

11-16 16:02:29.258 4994-4994/com.example.lql.kotlindemo E/###: 泛型约束:38.11###11-16 16:02:29.258 4994-4994/com.example.lql.kotlindemo E/###: 多重约束:88###11-16 16:02:29.258 4994-4994/com.example.lql.kotlindemo E/###: 多重约束:99###11-16 16:02:29.258 4994-4994/com.example.lql.kotlindemo E/###: 多重约束:888###11-16 16:02:29.258 4994-4994/com.example.lql.kotlindemo E/###: 多重约束:1024###

10、扩展:

所谓扩展,就是对已经有的类,但是不能修改源码的这种去增加一些方法。添加方法的时候要注意尽量不要和类中已经有的方法重名,如果非要重名,那类型也不要相同。简单来说就是别一毛一样。
看一下具体的写法:

//扩展函数:fun 接受者类型.新扩展函数名(参数类别){//函数实现}    //1、函数扩展    fun Int.square(): Int {        return this * this    }    //2、泛型函数扩展:求数字型数组中的最大元素    fun <T> Array<T>.biggest(): T            where T : Number,                  T : Comparable<T> {        var biggest = this[0]        for (t in this) {            if (t > biggest) {                biggest = t            }        }        return biggest    }    //    3、属性的扩展(普通属性)    val Int.next: Int        get() = this + 1    //4、泛型属性    数字类型的半径   的面积    val <T : Number> T.area: Double        get() = 3.1425926 * this.toDouble() * this.toDouble()

使用:

 LogUtils.Loge("函数扩展:" + 3.square())        val a = arrayOf(1, 2, 3, 4, 5, 8)        LogUtils.Loge("求最大" + a.max())        val biggest = a.biggest()        LogUtils.Loge("自己写一个求最大:" + biggest)        LogUtils.Loge("属性扩展:" + 3.next)        LogUtils.Loge("属性泛型扩展:" + 3.area)        LogUtils.Loge("属性泛型扩展:" + 'B'.toByte().area)

Log:

11-16 16:16:59.348 4994-4994/com.example.lql.kotlindemo E/###: 函数扩展:9###11-16 16:16:59.348 4994-4994/com.example.lql.kotlindemo E/###: 求最大8###11-16 16:16:59.348 4994-4994/com.example.lql.kotlindemo E/###: 自己写一个求最大:8###11-16 16:16:59.348 4994-4994/com.example.lql.kotlindemo E/###: 属性扩展:4###11-16 16:16:59.348 4994-4994/com.example.lql.kotlindemo E/###: 属性泛型扩展:28.283333399999997###11-16 16:16:59.348 4994-4994/com.example.lql.kotlindemo E/###: 属性泛型扩展:13689.1333656###

这一部分,大家一看就知道具体的意思了,就不解释了。

好啦,通过两篇文章记录了一下Kotlin中变量的定义、元组的使用、循环控制流的使用、类的相关使用、异常处理、接口、泛型和扩展部分的内容。最开始学习Kotli就先聊这么多。我需要继续学习了。还是上一篇中的那句话,刚开始学习使用Kotlin,可能对概念以及用法的认识有偏差,如有错误,希望大家给予指正!

原创粉丝点击