package com.zj.example.kotlin.shengshiyuan.helloworld.generics.kotlin.test5

/**
 * Created by zhengjiong
 * date: 2018/2/25 21:07
 */

interface Producer<out T> {
    fun produce(): T
}

interface Consumer<in T> {
    fun consume(item: T)
}


open class Fruit

open class Apple : Fruit()

class ApplePear : Apple()

class FruitProducer : Producer<Fruit> {
    override fun produce(): Fruit {
        return Fruit()
    }
}

class AppleProducer : Producer<Apple> {
    override fun produce(): Apple {
        return Apple()
    }
}

class ApplePearProducer : Producer<ApplePear> {
    override fun produce(): ApplePear {
        return ApplePear()
    }
}

private fun producerTest() {
    //对于"out"泛型来说, 我们可以将子类型对象赋给父类型引用
    val producer1: Producer<Fruit> = FruitProducer()        //success
    val producer2: Producer<Fruit> = AppleProducer()        //success
    val producer3: Producer<Fruit> = ApplePearProducer()    //success

    //这里返回的是Fruit类型的变量
    val fruit = producer2.produce()


    //val producer4: Producer<ApplePear> = AppleProducer()    //error
    val producer5: Producer<ApplePear> = ApplePearProducer()  //success
}

fun main(args: Array<String>) {
    producerTest()
    consumerTest()
}

private fun consumerTest() {
    //对于"in"泛型来说, 我们可以将父类型对象赋给子类型引用
    val consumer1: Consumer<ApplePear> = FruitConsumer()
    val consumer2: Consumer<ApplePear> = AppleConsumer()
    val consumer3: Consumer<ApplePear> = ApplePearConsumer()

    consumer2.consume(ApplePear())//这里的输入参数类型是ApplePear类型的
}


class FruitConsumer : Consumer<Fruit> {
    override fun consume(item: Fruit) {

    }
}

class AppleConsumer : Consumer<Apple> {
    override fun consume(item: Apple) {
    }
}

class ApplePearConsumer : Consumer<ApplePear> {
    override fun consume(item: ApplePear) {

    }
}