初始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,可能对概念以及用法的认识有偏差,如有错误,希望大家给予指正!
- 初始Kotlin<下>
- 初始Kotlin<上>
- Android 开发之 Kotlin 初始篇
- Android 开发之 Kotlin 初始篇
- Kotlin入门系列教程—初始篇
- Android 开发之 Kotlin 初始篇
- Kotlin下配置DataBinding
- 入门kotlin(下)
- Kotlin——初始Kotlin及Android Studio配置环境开发HelloKotlin
- Linux下初始结构分析
- 初始
- 初始
- 初始
- 初始
- 初始
- 初始
- 初始
- 初始
- Visual Studio 2008 环境变量的配置(参考设置VS2010)
- 第十周项目一__验证算法(1)
- 2012年蓝桥杯题目微生物增殖
- Java性能优化之for循环
- Maven 创建web项目出现src/main/java, src/test/java已存在,但是Missing
- 初始Kotlin<下>
- C语言指针题集
- Java学习笔记1:数据类型-基本数据类型
- 十二、函数的参数
- oracle异常关闭,启动:ORA-24324: service handle not initialized
- 内存分配方式(一)
- 交叉熵损失函数
- Git学习笔记
- Socket网络编程(一)