泛型类的定义:
泛型类都是有主构造函数的,其主构造函数可以接受任何类型。
只需要在泛型类的后面加上<> 即可,里面定义泛型 T、M、K 等等
//定义一个泛型T
class Generate<T>(var t:T)
//定义多个泛型T K
class GenerateMore<T,K>(val t:T,val k:K)
泛型接口的定义:
在名字后面加 <>
//该接口定义一个泛型T
interface GenerateInter<T>{
//使用传过来的泛型
fun useT(t:T)
}
//该接口定义多个泛型T M
interface GenerateInterMore<T,M>{
//使用传过来的泛型
fun useT(t:T)
//使用传过来的多个泛型
fun useTM(t:T,m:M)
}
泛型方法的定义:
泛型方法的参数可以用泛型T表示。
//该方法定义一个泛型T
fun <T> generate(t:T){
println()
}
//该方法定义多个泛型T L
fun <T,L> generateMore(t:T,l:L){
}
多泛型参数:
泛型类 泛型函数 可以有多个不同 的泛型参数
泛型类型T的约束:
让未知的泛型T 子类 继承某个父类类型,让泛型子类T的范围被约束缩小。
vararg 关键字 :可以表示多个泛型参数
多个泛型参数 vararg item: T 最终表示的是一个集合
var subject: Array<out T> = item
如果我想要获取多个泛型集合subject里的某一个具体的泛型数据T
operator fun get(index: Int):T?=subject[index].takeIf { available } fun fetch(index: Int): T? { return subject[index].takeIf { available }}
/**
*T : Human 表示对泛型T的类型约束:T指定的类型只能是继承Human的子类
* */
class MagicBox<T : Human>(vararg item: T) {
var available = false
private var subject: Array<out T> = item
operator fun get(index: Int):T?=subject[index].takeIf { available }
fun fetch(index: Int): T? {
return subject[index].takeIf { available }
}
//业务,把元素进行修改
//魔盒里面放的是男孩,取出来的时候,我给他改成了一个男人
//return -> R
/**
* 多泛型参数:泛型函数或泛型类可以有多个泛型参数。
* */
fun <R> fetch(index: Int, subjectModFunction: (T) -> R): R? {
return subjectModFunction(subject[index]).takeIf { available }
}
}
open class Human(val age: Int)
class Boy(val name: String, age: Int) : Human(age)
class Man(val name: String, age: Int) : Human(age)
class Dog(val weight: Int)
fun main() {
val box1: MagicBox<Boy> = MagicBox(
Boy("Jack", 15),
Boy("Jacky", 16),
Boy("John", 26)
)
box1.available = true
box1.fetch(0)?.run { println("you find $name") }
val man0 = box1.fetch(1)
man0?.run { println("当前的具体泛型数据是: ${name+age}") } //当前的具体泛型数据是: Jacky 16
box1.get(2)?.run { println("当前的具体泛型数据是: ${name+age}") } //当前的具体泛型数据是: John 26
val man = box1.fetch(2, subjectModFunction={its-> Man(its.name, its.age.plus(15))})
}
out T 协变
泛型类 将泛型类型T 作为泛型函数数据的返回,使用out T 。主要用来生产泛型数据T对象的
private var subject: Array<out T> = item
interface Production<out T>{ public fun product():T }
in T 逆变
泛型类 只是将泛型类型T,作为泛型函数的入参参数。主要用来消费使用 泛型对象T的
interface Consumer<in T>{
fun consume(item:T)
}
invariant 不变 泛型类 即将泛型T 作为泛型函数的数据返回(生产泛型数据T),又作为泛型函数的入参参数(消费使用 泛型对象T)
interface ProductionConsumer<T>{
fun product():T //返回泛型数据T 生产者
fun consume(item:T) //泛型数据T 作为参数,消费使用泛型数据T
}
为什么要使用in&out?
父类泛型对象转成子类泛型对象 in
子类泛型对象 转成父类泛型对象 out