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()

results matching ""

    No results matching ""