参考链接
Kotlin官方文档
https://kotlinlang.org/docs/home.html
中文网站
https://www.kotlincn.net/docs/reference/properties.html
本系列为参考Kotlin中文文档
https://download.csdn.net/download/u011109881/21418027
整理的笔记?
pdf也可以在这里下载
https://www.kotlincn.net/docs/kotlin-docs.pdf
部分示例来自bilibili 动脑学院的Kotlin 泛型的视频讲解
第二章 第九节 泛型
知识点
1 Kotlin中的泛型的基本用法
2 泛型函数?
3 多泛型参数
4 泛型约束
5 泛型中的类型推断
6 Kotlin中的型变
7 协变demo
8 逆变demo
9 协变与逆变示例在Java中的写法
笔记
fun main() {
// 1 Kotlin中的泛型的基本用法
// 可以装下任何类型的Box
val box1 = MagicBox("aaa")
println(box1.item)
val box2: MagicBox<Dog> = MagicBox(Dog("xiaohei"))
println(box2.item.name)
val box3: MagicBox<Boy> = MagicBox(Boy("zhangsan", 15))
println(box3.item.name + box3.item.age)
// 2 泛型函数
box2.avaliable = true
// 如果fetch返回值不是空 则执行run方法体
box2.fetch()?.run {
println("returned data ${this.name}")
}
box2.avaliable = false
val data = box2.fetch()?.run {
println("returned data ${this.name}")
}
println("data is $data")
// 3 多泛型参数
val box4: MagicBox<Boy> = MagicBox(Boy("zhangsan", 15))
box4.avaliable = true
// change 方法入参是Boy 返回类型是Man
// 为什么入参是Boy subjectModFun(subject)中 subject就是Boy类型的
val man: Man? = box4.change {
Man(it.name, it.age.plus(10))
}
man?.run { println("${this.name},${this.age}") }
// 4 泛型约束
// val box6: MagicBox1<Dog1> = MagicBox1(Dog1("xiaohei"))// 报错 Dog不是Human1类型
val box7: MagicBox1<Boy1> = MagicBox1(Boy1("xiaohei", 12))
val box8: MagicBox1<Man1> = MagicBox1(Man1("xiaohei", 22))
// 5 泛型中的类型推断
// 类型参数可以推断出来,例如从构造函数的参数或者从其他途径,允许省略类型参数
// 以下写法都是等价的
val box9: MagicBox<Int> = MagicBox<Int>(1)
val box10: MagicBox<Int> = MagicBox(1)
val box11 = MagicBox(1)// // 1 具有类型 Int,所以编译器知道我们说的是 Box<Int>。
// 6 Kotlin中的型变
// 型变分为两种协变和逆变
// 协变: 父类可以使用的地方子类也可以使用
// 父类引用指向子类对象
// 假设FastFood是Food的子类 如果有Box<FastFood>是Box<Food>的子类 即可以用Box<FastFood>替换Box<Food>
// 我们称Box的泛型是协变的 (我们的例子中Box是Producer)
// 逆变: 子类可以使用的地方父类也可以使用
// 子类引用指向父类对象
// 假设FoodStore是FastFoodStore的父类 如果有Box<FoodStore>是Box<FastFoodStore>的子类 即可以用Box<FoodStore>替换Box<FastFoodStore>
// 我们称Box的泛型是逆变的 (我们的例子中Box是Consumer)
// 7 协变demo
val foodProducer1: Producer<Food> = FoodStore()
foodProducer1.produce()
val fastFoodProducer1: Producer<FastFood> = FastFoodStore()
fastFoodProducer1.produce()
val fastFoodProducer2: Producer<Food> = FastFoodStore()
fastFoodProducer2.produce()
// BurgerStore里面泛型为Burger 但是赋值的时候可以使用Producer<Burger> Producer<FastFood> Producer<Food>
// 看起来Producer<Burger> Producer<FastFood> Producer<Food> 都可以指向 子类泛型Burger
// 原因是Producer使用了out修饰符
val burgerProducer1: Producer<Burger> = BurgerStore()
burgerProducer1.produce()
val burgerProducer2: Producer<FastFood> = BurgerStore()
burgerProducer2.produce()
val burgerProducer3: Producer<Food> = BurgerStore()
burgerProducer3.produce()
// 8 逆变demo
// People里泛型为Food 然而 Consumer<Food> Consumer<FastFood> Consumer<Burger>等Food子类的泛型也能指向父类Food的泛型
// 是因为Consumer使用了逆变 in 操作符
val foodConsumer: Consumer<Food> = People()
// 输出的都是 People eat Food
foodConsumer.consume(Food())
foodConsumer.consume(FastFood())
foodConsumer.consume(Burger())
val foodConsumer2: Consumer<FastFood> = People()
foodConsumer2.consume(FastFood())
foodConsumer2.consume(Burger())
val foodConsumer3: Consumer<Burger> = People()
foodConsumer3.consume(Burger())
val fastFoodConsumer: Consumer<FastFood> = ModernPeople()
fastFoodConsumer.consume(FastFood())
fastFoodConsumer.consume(Burger())
val fastFoodConsumer2: Consumer<Burger> = ModernPeople()
fastFoodConsumer2.consume(Burger())
val burgerConsumer: Consumer<Burger> = American()
burgerConsumer.consume(Burger())
// 9 协变与逆变示例在Java中的写法 参见 D0309GenericJava
}
// out 协变 这里用在返回值上
interface Producer<out T> {
fun produce(): T
}
// in 逆变 这里用在输入参数上
interface Consumer<in T> {
fun consume(item: T)
}
// 不变
interface ProduceConsumer<T> {
fun produce(): T
fun consume(item: T)
}
open class Food
open class FastFood : Food()
class Burger : FastFood()
// 生产者 结合协变 out使用 协变 用在参数
class FoodStore : Producer<Food> {
override fun produce(): Food {
println("produce food")
return Food()
}
}
class FastFoodStore : Producer<FastFood> {
override fun produce(): FastFood {
println("produce fast food")
return FastFood()
}
}
class BurgerStore : Producer<Burger> {
override fun produce(): Burger {
println("produce burger")
return Burger()
}
}
// 消费者 结合in使用 逆变 用在返回值
class People : Consumer<Food> {
override fun consume(item: Food) {
println("People eat Food")
}
}
class ModernPeople : Consumer<FastFood> {
override fun consume(item: FastFood) {
println("ModernPeople eat FastFood")
}
}
class American : Consumer<Burger> {
override fun consume(item: Burger) {
println("American eat Burger")
}
}
// 4 泛型约束
// 利用继承约束泛型类型 和Java的extends有点像
abstract class Human1(val age: Int)
class Man1(val name: String, age: Int) : Human1(age)
class Boy1(val name: String, age: Int) : Human1(age)
class Dog1(val name: String)
class MagicBox1<T : Human1>(var item: T) {
var avaliable: Boolean = false
private var subject: T = item
fun fetch(): T? {
// 如果avaliable是true 返回 subject 否则返回null
return subject.takeIf { avaliable }
}
}
// 1 Kotlin中的泛型的基本用法
class Man(val name: String, val age: Int)
class Boy(val name: String, val age: Int)
class Dog(val name: String)
class MagicBox<T>(var item: T) {
var avaliable: Boolean = false
private var subject: T = item
// 2 泛型函数 返回一个T类型的对象
fun fetch(): T? {
// 如果avaliable是true 返回 subject 否则返回null
return subject.takeIf { avaliable }
}
// 3 多泛型参数
// change方法 输入类型T 返回类型R
fun <R> change(subjectModFun: (T) -> R): R? {
return subjectModFun(subject).takeIf { avaliable }
/* 等价下面的内容
return if (avaliable){
subjectModFun(subject)
}else{
null
}*/
}
}
class D0309Generic
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class D0309GenericJava {
static void copyAll2(Collection<? extends Object> collection) {
// Collection<String> 是 Collection<? extends Object>的子类
}
static void copyAll3(Collection<Object> collection) {
// Collection<String> 不是 Collection<Object>的子类
}
static void copyAll4(Collection<? super String> collection) {
// Collection<Object> 是 Collection<? super String>的子类
}
static void copyAll(Collection<Object> to, Collection<String> from) {
to.addAll(from);
// addAll的实际定义 :boolean addAll(Collection<? extends E> var1);
// 而不是想象中的 boolean addAll(Collection<E> items);
// 想象中的定义对于这种简单声明的 addAll 将不能编译:
// 因为Collection<String> 不是 Collection<Object> 的子类型
// 但实际上可以编译通过 是因为Collection<String> 是 Collection<? extends Object>的子类
}
public static void main(String[] args) {
// 几种基本类型的子类父类关系
List<String> strings = new ArrayList<>();
List<Object> obj = new ArrayList<>();
// obj = strings; List<Object> 不是 List<String> 的父类
// strings = obj; List<String>不是 List<Object> 的子类
copyAll(obj,strings);
copyAll2(strings);
//copyAll3(strings);// 编译报错
copyAll4(obj);
// Java协变的写法 父类对象指向子类引用
// 协变: 父类可以使用的地方子类也可以使用
// 父类引用指向子类对象
Producer<? extends Food> foodStore = new FoodStore();
foodStore.produce();
Producer<? extends Food> fastFoodStore = new FastFoodStore();
fastFoodStore.produce();
Producer<? extends FastFood> fastFoodStore2 = new FastFoodStore();
fastFoodStore2.produce();
Producer<? extends Food> burgerStore1 = new BurgerStore();
burgerStore1.produce();
Producer<? extends FastFood> burgerStore2 = new BurgerStore();
burgerStore2.produce();
Producer<? extends Burger> burgerStore3 = new BurgerStore();
burgerStore3.produce();
// Java逆变的写法
// 逆变: 子类可以使用的地方父类也可以使用
// 子类引用指向父类对象
Consumer<? super Food> foodConsumer = new People();
foodConsumer.consume(new Food());
foodConsumer.consume(new FastFood());
foodConsumer.consume(new Burger());
Consumer<? super FastFood> foodConsumer2 = new People();
foodConsumer2.consume(new FastFood());
foodConsumer2.consume(new Burger());
Consumer<? super Burger> foodConsumer3 = new People();
foodConsumer3.consume(new Burger());
Consumer<? super FastFood> fastFoodConsumer = new ModernPeople();
fastFoodConsumer.consume(new FastFood());
fastFoodConsumer.consume(new Burger());
Consumer<? super Burger> fastFoodConsumer2 = new ModernPeople();
fastFoodConsumer2.consume(new Burger());
Consumer<? super Burger> burgerConsumer = new American();
burgerConsumer.consume(new Burger());
}
// 协变 这里用在返回值上
interface Producer<T> {
T produce();
}
// 逆变 这里用在输入参数上
interface Consumer<T> {
void consume(T food);
}
public static class Food {
}
public static class FastFood extends Food {
}
public static class Burger extends FastFood {
}
// 生产者 结合协变 out使用 协变 用在参数
static class FoodStore implements Producer<Food> {
@Override
public Food produce() {
System.out.println("produce food");
return new Food();
}
}
static class FastFoodStore implements Producer<FastFood> {
@Override
public FastFood produce() {
System.out.println("produce fast food");
return new FastFood();
}
}
static class BurgerStore implements Producer<Burger> {
@Override
public Burger produce() {
System.out.println("produce burger");
return new Burger();
}
}
static class People implements Consumer<Food> {
@Override
public void consume(Food food) {
System.out.println("People eat Food");
}
}
static class ModernPeople implements Consumer<FastFood> {
@Override
public void consume(FastFood food) {
System.out.println("ModernPeople eat FastFood");
}
}
static class American implements Consumer<Burger> {
@Override
public void consume(Burger food) {
System.out.println("American eat Burger");
}
}
}
|