Kotlin의 인앤아웃 유형 변형

5278 단어 kotlin

kotlin에서 제네릭을 정의한 적이 있다면 in 또는 out 키워드를 사용하여 .

공식적으로 이것은 반공변과 공변을 정의하는 방법입니다. 그것에 대해 배우는 데 시간이 좀 걸렸습니다. 여기에서 내가 어떻게 이해하고 암기하는지 설명하겠습니다.

쉽게 기억되는 인앤아웃


출력(공변형)



제네릭 클래스가 함수의 출력으로 제네릭 유형만 사용하는 경우 출력이 사용됩니다.

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

저는 그것을 생산 클래스/인터페이스라고 부릅니다. 주로 일반 유형의 출력을 생성하기 때문입니다. 따라서 매우 간단하게 기억할 수 있습니다.

생산 = 출력 = 아웃

In(반공분산 유형)



제네릭 클래스가 함수의 입력으로 제네릭 유형만 사용하는 경우 in이 사용됩니다.

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

주로 일반 유형을 소비하므로 소비자 클래스/인터페이스라고 부릅니다. 따라서 매우 간단하게 기억할 수 있습니다.

소비 = 입력 = 안으로

불변 유형



하나의 제네릭 클래스가 제네릭 유형을 함수에 대한 입력 및 출력으로 사용하는 경우 입력 또는 출력이 사용되지 않으며 불변입니다.

interface ProductionConsumer<T> {
    fun produce(): T
    fun consume(item: T)
}

인과 아웃을 사용하는 이유는 무엇입니까?



이제 inandout이 언급될 때 쉽게 기억할 수 있습니다. 그 의미는 무엇입니까? 거기에 가기 전에 버거 클래스 개체를 정의하겠습니다. 그것은 음식의 일종인 패스트푸드입니다.

단순한 클래스 계층 구조



open class Food
open class FastFood : Food() 
class Burger : FastFood()

버거 생산



위에서 정의한 일반 생산 인터페이스를 살펴보면 아래와 같이 제품 식품, 패스트푸드 및 버거로 확장해 보겠습니다.

class FoodStore : Production<Food> {
    override fun produce(): Food {
        println("Produce food")
        return Food()
    }
}

class FastFoodStore : Production<FastFood> {
    override fun produce(): FastFood {
        println("Produce food")
        return FastFood()
    }
}

class InOutBurger : Production<Burger> {
    override fun produce(): Burger {
        println("Produce burger")
        return Burger()
    }
}

이제 Food Production 보유자를 보유하고 모든 이들을 여기에 할당할 수 있습니다.

val production1 : Production<Food> = FoodStore()
val production2 : Production<Food> = FastFoodStore()
val production3 : Production<Food> = InOutBurger()

버거나 패스트푸드 생산은 여전히 ​​식품 생산입니다. 따라서

For 'out' generic, we could assign a class of subtype to class of super-type
If we change to below, it would error out, because food or fastFood is not just a burger production.



val production1 : Production<Burger> = FoodStore()  // Error
val production2 : Production<Burger> = FastFoodStore()  // Error
val production3 : Production<Burger> = InOutBurger()

버거 소비자



이제 위에서 정의한 일반 소비자 인터페이스를 살펴보고 아래와 같이 음식, 패스트푸드 및 버거를 소비하도록 확장해 보겠습니다.

class Everybody : Consumer<Food> {
    override fun consume(item: Food) {
        println("Eat food")
    }
}

class ModernPeople : Consumer<FastFood> {
    override fun consume(item: FastFood) {
        println("Eat fast food")
    }
}

class American : Consumer<Burger> {
    override fun consume(item: Burger) {
        println("Eat burger")
    }
}

이제 Burger Consumer 보유자를 확보하고 그들 모두를 할당할 수 있습니다.

val consumer1 : Consumer<Burger> = Everybody()
val consumer2 : Consumer<Burger> = ModernPeople()
val consumer3 : Consumer<Burger> = American()

여기에서 버거 소비자는 미국인이며, ModernPeople의 일부이기도 하고, Everybody의 일부이기도 합니다. 따라서

For ‘in' generic, we could assign a class of super-type to class of subtype
If we change to below,it would error out,because consumer of Food althought could be American or ModernPeople,it is not just American or just ModernPeople .



val consumer1 : Consumer<Food> = Everybody()
val consumer2 : Consumer<Food> = ModernPeople()  // Error
val consumer3 : Consumer<Food> = American()  // Error

In과 Out을 기억하는 또 다른 방법



위의 내용을 감안할 때 언제 무엇을 사용해야 하는지를 아는 또 다른 이유는

SuperType could be assigned subtype, use IN
SubType could be assigned to SuperType, use OUT




from > In and out type variant of Kotlin

좋은 웹페이지 즐겨찾기