一、泛型类
class MagicBox<T>(item:T){
private var subject:T =item
}
class Boy(val name:String,val age:Int)
class Dog(val weight:Float)
fun main(){
var magicBoxBoy:MagicBox<Boy> = MagicBox(Boy("Jack", 28))
var magicBoxDog:MagicBox<Dog> = MagicBox(Dog(20f))
}
二、泛型函数
class MagicBox<T>(item: T) {
var available = false
private var subject: T = item
fun fetch(): T? {
return subject.takeIf {
available
}
}
}
class Boy(val name: String, val age: Int)
class Dog(val weight: Float)
fun main() {
var magicBoxBoy: MagicBox<Boy> = MagicBox(Boy("Jack", 28))
var magicBoxDog: MagicBox<Dog> = MagicBox(Dog(20f ))
magicBoxBoy.available=true
magicBoxBoy.fetch()?.run {
println("$name")
}
}
三、多泛型参数
class MagicBox<T>(item: T) {
var available = false
private var subject: T = item
fun <R> fetch(subjectModFunction: (T) -> R): R? {
return subjectModFunction(subject).takeIf { available }
}
}
四、泛型类型的约束
声明T类型是Human的子类
class MagicBox<T:Human>(item: T) {
var available = false
private var subject: T = item
fun <R> fetch(subjectModFunction: (T) -> R): R? {
return subjectModFunction(subject).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: Float)
fun main() {
var magicBoxBoy: MagicBox<Boy> = MagicBox(Boy("Jack", 28))
// var magicBoxDog: MagicBox<Dog> = MagicBox(Dog( 20))
}
五、out(协变)和in(逆变)
1.out(协变),如果泛型类只将泛型类型作为函数的返回(输出),那么使用out,可以称之为生产类/接口,因为它主要是用来生产(produce)指定的泛型对象。
interface Production<out T> {
fun product(): T
}
2.in(逆变),如果泛型类只将泛型类型作为函数的入参(输入),那么使用in,可以称之为消费者类/接口,因为它主要是用来消费(consume)指定的泛型对象。
interface Consumer<in T> {
fun consume(item: T)
}
3.(不变)如果泛型类既将泛型类型作为函数参数,又将泛型类型作为函数的输出,那么既不用out也不用in
4.父类泛型对象可以赋值给子类泛型对象,使用in;子类泛型对象可以赋值给父类泛型对象,使用out
interface ProductionConsumer<T>{
fun product():T
fun consume(item:T)
}
interface Production<out T> {
fun product(): T
}
open class Food()
open class FastFood : Food()
class Hamburger : FastFood()
class FoodStore:Production<Food>{
override fun product(): Food {
return Food()
}
}
class FastFoodStore :Production<FastFood>{
override fun product(): FastFood {
return FastFood()
}
}
class HamburgerStore:Production<Hamburger>{
override fun product(): Hamburger {
return Hamburger()
}
}
class EveryBody:Consumer<Food>{
override fun consume(item: Food) {
println("eat food")
}
}
class ModernPeople:Consumer<FastFood>{
override fun consume(item: FastFood) {
println("eat fastFood")
}
}
class American:Consumer<Hamburger>{
override fun consume(item: Hamburger) {
println("eat hamburger")
}
}
fun main() {
val food: Production<Food> = FoodStore()
//变量的类型声明中使用了父类类型,这java中这样赋值会有编译错误,但是kotlin中通过out实现了
//子类泛型对象可以赋值给父类泛型对象,使用out
val fastFood: Production<Food> = FastFoodStore()
//父类泛型对象可以赋值给子类泛型对象,使用in
val consumer :Consumer<Hamburger> = EveryBody()
}
六、reified
class MagicBox<T : Human>(item: T) {
// fun <T> randomOrBackup(backup: () -> T): T {
// val list = listOf(Boy("Jack", 28), Man("Bob", 24))
// val random = list.shuffled().first()
// return if (random is T) {
// random
// } else {
// backup()
// }
// }
//reified 配合inline关键字
inline fun <reified T> randomOrBackup(backup: () -> T): T {
val list = listOf(Boy("Jack", 28), Man("Bob", 24))
val random = list.shuffled().first()
return if (random is T) {
random
} else {
backup()
}
}
}
网友评论