10天学会kotlin DAY7 接口 泛型 协变 逆变


前言

使用纯代码 加 注释的方式,可以更快的理解源码
如果你喜欢,请点个赞,后期会不断的深入讲解


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<T>
//    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<T>
//    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
    }
}

总结

🤩
🎉 原 创 不 易 , 还 希 望 各 位 大 佬 支 持 一 下 \textcolor{blue}{原创不易,还希望各位大佬支持一下}

👍 点 赞 , 你 的 认 可 是 我 创 作 的 动 力 ! \textcolor{green}{点赞,你的认可是我创作的动力!}

🌟 收 藏 , 你 的 青 睐 是 我 努 力 的 方 向 ! \textcolor{green}{收藏,你的青睐是我努力的方向!}

✏️ 评 论 , 你 的 意 见 是 我 进 步 的 财 富 ! \textcolor{green}{评论,你的意见是我进步的财富!}

  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

半身风雪

感谢打赏,你的鼓励,是我创作的

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值