kotlin 基础 接口 泛型 协变 逆变
kotlin 基础入门
文章目录
- kotlin 基础入门
- 前言
-
- 1、接口的定义
- 2、抽象类
- 3、定义泛型类
- 4、泛型函数
- 5、泛型变换
- 6、泛型类型约束
- 7、vararg 关键字(动态参数)
- 8、[] 操作符
- 9、out 协变 & in 逆变 的使用
前言
使用纯代码 加 注释的方式,可以更快的理解源码
如果你喜欢,请点个赞,后期会不断的深入讲解
1、接口的定义
// 接口里面的所有的成员 和 接口本身,都是 public open 的// 接口不能有主构造// 实现类不仅仅要重写接口的函数,也要重写接口的成员 val mouse = Mouse() println(mouse.insertUBS()) val keyBoard = KeyBoard()// 可以任意的更改set 的值。 keyBoard.usbInsertDevice = "王五" println(keyBoard.insertUBS())interface IUSB { var usbVersionInfo: String //USB 相关版本的信息 var usbInsertDevice: String //USB 插入的设备信息 fun insertUBS(): String // 插入UBS 的实现}// 鼠标USB 的实现class Mouse(override var usbVersionInfo: String = "USB 6.9", override var usbInsertDevice: String = "鼠标插入了USB 接口") : IUSB { override fun insertUBS(): String { return "版本号为:$usbVersionInfo 的 $usbInsertDevice" }}// 键盘 USB 的实现class KeyBoard : IUSB {// 下面的set ,get 都会持有 field,如果没有给 usbVersionInfo 赋值,意味着 field 是没法让set/get 持有的 override var usbVersionInfo: String = "高级键盘" get() = field set(value) { field = value } override var usbInsertDevice: String = "接入了USB" get() { println("你可以get 到 $field 的数据出去") return field } set(value) { field = value println("你set 进来了 $field 的值") } override fun insertUBS(): String { return "键盘的的内容输出是: $usbVersionInfo , $usbInsertDevice" }}
2、抽象类
// 在kotlin 中,抽象类和Java 完全是一样的 val mainActivity = MainActivity() mainActivity.show()abstract class BaseActivity{ fun onCreate(){ setContentView(getLayoutID()) initView() initData() } private fun setContentView(layoutID: Int) = println("加载$layoutID 布局中") abstract fun getLayoutID(): Int abstract fun initView() abstract fun initData() fun show(){ onCreate() }}class MainActivity() : BaseActivity(){ override fun getLayoutID(): Int { return 662 } override fun initView() { return println("加载view") } override fun initData() { return println("加载数据") }}
3、定义泛型类
// 在kotlin 中,泛型的定义,和Java 也没有什么太大区别 Person("张三").show() Person(11).show() Person(22.3f).show() Person('男').show()class Person<T> (private val obj: T){ fun show() = println("我是泛型,你传啥,我都能输出 $obj")}
4、泛型函数
println(Person(true, "张三").show()) println(Person(true, 11).show()) println(Person(false, 33.3f).show()) println(Person(false, '男').show())// 泛型函数, 使用Boolean 来控制对象是否返回, 运用takeIf (为true就返回对象本身,false 就返回null)class Person<T> (private val isR: Boolean, private val obj: T){ fun show() = obj.takeIf { isR }}
5、泛型变换
val person = Person(true, "学生") person.map { println(it) }class Person<T>(val isMap: Boolean = false, val inputType: T){// 模仿RxJava T 是要变换的输入类型, R是变换后输出的类型// map 返回的类型有可能是R,也有可能是null inline fun <R> map(mapAction: (T) -> R) = mapAction(inputType).takeIf { isMap }}
6、泛型类型约束
val person = Person("tiger", 88) val study = Study("tiger", 18) println(TextGeneric(person, true).show()) println(TextGeneric(study).show())open class MyAnyClass(name: String) { // 顶级父类}open class Person(name: String, age: Int) : MyAnyClass(name) {}class Study(name: String, age: Int) : Person(name, age) {}class Teacher(name: String, age: Int) : Person(name, age) {}class TextGeneric<T : Person>(private val inputTypeInfo: T, private val isR: Boolean = false) {// 万能的返回器 fun show() = inputTypeInfo.takeIf { isR }}
7、vararg 关键字(动态参数)
val p = Person("tiger", '男', 333, 32.5f, isR = true) println(p.showObject(1)) println(p.showObject(2)) println(p.showObject(3)) p.mapObject(1){ println("转换成String $it") }class Person<T>(vararg objects: T, val isR: Boolean) { // objetArray: Array// out 指定 T 只能读取,不能修改 private val objectArray: Array<out T> = objects // showObject(index) fun showObject(index: Int) = objectArray[index].takeIf { isR } // mapObject(index 变换成 Lambda) objectArray[index] fun <O> mapObject(index: Int, mapAction: (T) -> O) { mapAction(objectArray[index]) }}
8、[] 操作符
val p = Person("tiger", '男', 333, 32.5f, isR = true) println(p[1]) println(p[2]) println(p[3])class Person<T>(vararg objects: T, val isR: Boolean) { // objetArray: Array// out 指定 T 只能读取,不能修改 private val objectArray: Array<out T> = objects // operator 运算符重载,在使用的时候,可以直接使用 [] 调用就可以了 operator fun get(index: Int) = objectArray[index].takeIf { isR }}
9、out 协变 & in 逆变 的使用
out 协变:父类 = 子类
in 逆变: 子类 = 父类
val setClass = SetClass<String>() println(setClass.setItem("tiger")) val getClass = GetClass("张三") println(getClass.getItem())// in T 逆变 【 in T SetClass 只能修改,更改,不能被外界获取 】class SetClass<in T>{ fun setItem(item: T): String { return "你要设置的数据是:$item" }}// out T 协变 【 out T GetClass 可以被获取,读取,不能被修改】class GetClass<out T>(_item: T) { private val item: T = _item fun getItem(): T { return item }}