in out 泛型轉型
泛型轉型主要是透過「泛型介面」轉型。
Interface 介面
Product生產者介面
out視為輸出,方法只能傳回return T類型的物件。
以下是生產者介面,只有一個方法,product()負責生產T類型的東西。
實作的子類別,必須實作product()方法。
1
2
3
interface Production<out T> {
    fun product() : T
}
Consumer消費者介面
in視為輸入,方法只能傳入T類型的參數,不能有傳回值。
以下是消費者介面,只有一個方法,consume()負責接收T類型參數。
實作的子類別,必須實作consume()方法。
1
2
3
interface Consumer<in T> {
    fun consume(item:T)
}
父類別與子類別
父類別是Animal,子類別是Fish
1
2
3
open class Animal
class Fish:Animal()
實作Interface
覆寫Product介面方法
實作的Product介面的子類別,一定要覆寫product()方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
// 賣魚商店
class FishStroe:Production<Fish> {
    override fun product(): Fish {
        return Fish()
    }
}
// 賣動物商店
class AnimalStroe:Production<Animal> {
    override fun product(): Animal {
        return Animal()
    }
}
覆寫Consumer介面方法
實作的Consumer介面的子類別,一定要覆寫consume()方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
// 買魚的消費者
class FishConsumer:Consumer<Fish> {
    override fun consume(item: Fish) {
        println("eat fish")
    }
}
// 買動物的消費者
class AnimalConsumer:Consumer<Animal> {
    override fun consume(item: Animal) {
        println("eat Animal")
    }
}
泛型類別透過介面轉型
子類泛型轉父類泛型
下面程式碼,等號左邊是Production介面,泛型類型是Animal,但實際上是FishStore的類別,執行product()方法,收到的是魚Fish物件。
1
2
3
    val animalStroe:Production<Animal> = FishStroe()
    val obj = animalStroe.product()
    println(obj.toString())
Fish@1be6f5c3
父類泛型轉子類泛型
下面程式碼,等號左邊是Consumer介面,泛型類型是Fish,等號右邊指派的是AnimalConsumer,呼叫consume()方法,實際上是執行AnimalConsumer.consume()方法。
1
2
    val fishConsumer:Consumer<Fish> = AnimalConsumer()
    fishConsumer.consume(Fish())
eat Animal
Java無法泛型轉型
子類泛型轉父類泛型
以下編譯不過。
1
List<Animal> list = new ArrayList<Fish>();
Kotlin透過泛型介面,可以子類泛型轉型成父類泛型。
1
val animalStroe:Production<Animal> = FishStroe()
父類泛型轉子類泛型
以下編譯不過。
1
List<Fish> list = new ArrayList<Animal>();
Kotlin透過泛型介面,可以父類泛型轉型成子類泛型。
1
val fishConsumer:Consumer<Fish> = AnimalConsumer()