代码语言:javascript复制
//泛型
class MagicBox<T>(item:T){
var available = false
private var subject:T = item
fun fetch() : T? {
return subject.takeIf { available }
}
//参数是匿名函数,传入T,返回R
fun <R> fetch(subjectFunction: (T) -> R) : R? {
return subjectFunction(subject).takeIf { available }
}
}
class Boy(val name:String, val age:Int)
class Man(val name:String, val age:Int)
class Dog(val weight:Int)
fun main() {
val box1 = MagicBox(Boy("java", 10))
val box2 = MagicBox(Dog(10))
box1.available = true
box1.fetch()?.run {
println("you find $name")
}
val man = box1.fetch {
Man(it.name, it.age 10)
}
println("${man?.name}, ${man?.age}")
}
泛型in和out关键字
代码语言:javascript复制//out
interface Production<out T>{
fun product(): T
}
//in
interface Consumer<in T>{
fun consume(item: T)
}
//不变
interface ProductionConsumer<T>{
fun product():T
fun consume(item: T)
}
open class Food
open class FastFood: Food()
class Burger : FastFood()
class FoodStore : Production<Food>{
override fun product(): Food {
println("Produce food")
return Food()
}
}
class FastFoodStore : Production<FastFood>{
override fun product(): FastFood {
println("Produce FastFood")
return FastFood()
}
}
class BurgerStore : Production<Burger>{
override fun product(): Burger {
println("Produce Burger")
return Burger()
}
}
class EveryBody: Consumer<Food>{
override fun consume(item: Food) {
println("consume food")
}
}
class ModernPeople: Consumer<FastFood>{
override fun consume(item: FastFood) {
println("consume FastFood")
}
}
class American: Consumer<Burger>{
override fun consume(item: Burger) {
println("consume FastFood")
}
}
fun main() {
//子类泛型对象可以赋值给父类泛型对象,用out
val production1: Production<Food> = FoodStore()
val production2: Production<Food> = FastFoodStore()
val production3: Production<Food> = BurgerStore()
//父类泛型对象可以赋值给子类泛型对象,用in
val consumer1: Consumer<Burger> = EveryBody()
val consumer2: Consumer<Burger> = ModernPeople()
val consumer3: Consumer<Burger> = American()
}
reified关键字
- 和inline一起使用,reified关键字能帮你检查泛型的参数类型。kotlin不允许对泛型参数T做类型检查,因为泛型参数类型会被类型擦除,也就是说T的类型信息在运行时是不可知的
//泛型 //inline和reified关键字一起使用,以便检查泛型参数类型
class MagicBox2<T: Human>(){
//随机产生一个对象,如果不是指定类型的对象,则通过backup生成指定类型的对象
inline fun <reified T> randomOrBackup(backup:() -> T): T{
val items = listOf(
Boy2("Jav2k",30),
Man2("John3", 45))
val random = items.shuffled().first()
println(random)
return if (random is T) {
random
} else{
backup()
}
}
}
码字不易,求转发,求点在看,求关注,感谢!