kotlin 接口 泛型 协变 逆变
【摘要】 @[TOC](kotlin 接口 泛型 协变 逆变) 前言使用纯代码 加 注释的方式,可以更快的理解源码如果你喜欢,请点个赞,后期会不断的深入讲解 1、接口的定义// 接口里面的所有的成员 和 接口本身,都是 public open 的// 接口不能有主构造// 实现类不仅仅要重写接口的函数,也要重写接口的成员 val mouse = Mouse() print...
@[TOC](kotlin 接口 泛型 协变 逆变)
前言
使用纯代码 加 注释的方式,可以更快的理解源码
如果你喜欢,请点个赞,后期会不断的深入讲解
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
}
}
总结
🤩
🎉
👍
🌟
✏️
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)