Kotlin - Generics (1) : Invariance Types

WindSekirun (wind.seo)·2022년 4월 26일
0

이 글은 기존 운영했던 WordPress 블로그인 PyxisPub: Development Life (pyxispub.uzuki.live) 에서 가져온 글 입니다. 모든 글을 가져오지는 않으며, 작성 시점과 현재 시점에는 차이가 많이 존재합니다.

작성 시점: 2017-09-06

Invariance Types

한 가지 상황을 가정해보자.

Person 이란 기존 클래스가 있다고 해보자.

open class Person

그리고 이 Person 클래스를 상속하는 Employee 라는 클래스가 있다고 해보자.

class Employee: Person()

그리고, 한 메소드에서는 Person을 파라미터로 가진다고 해보자.

fun operate(person: Person)

이 파라미터에는 Person, Employee 둘 다 받을 수 있는데, Employee는 Person 의 아류형(Subtype)이기 때문이다.

이번엔 좀 다른 상황이다.

다른 메소드에서 Array 을 파라미터로 가진다고 해보자.

fun operate(person: Array)

\
그러면 오직 Person만 받을 수 있는데, 이는 Array 는 Array의 아류형이 아니기 때문이다.

이렇기 때문에, Invariant types (불변 유형) 란 개념이 나온다.

Employee 가 Person의 아류형이라도, Array 는 Array 의 아류형이 아니고, Array 는 Array 의 아류형이 아니면 불변 유형이라 정한다.


사실, 자바의 모든 클래스는 불변형이다. 그렇기에 말도 안되는 상황이 나올 수 있다.

Employee 는 Person 의 아류형인데, 왜 제너릭으로는 넘기지 못하지?

Effective Java, item 28번 Use bounded wild cards to increase API flexibility 에 문제가 잘 설명되어 있다.

위에서 설명한 대로, 자바의 모든 클래스는 불변형이기에 제너릭에서는 상속 관계의 클래스를 넘기지 못한다.

그래서 자바에는 이런 문제를 해결하기 위해서 와일드카드를 사용하여, <? extends E> 식으로 제너릭으로 넘기도록 처리했다.

? extends E 라고 선언함으로써 E 자체가 아닌, E 또는 E의 일부 하위 유형을 수집할 수 있게 한다. 이럼으로서 extends 상한 값이 있는 와일드 카드는 공변성을 생성할 수 있는 것이다.

조슈아는 '최대한의 유연성을 위해 producers 또는 consumers 를 대변하는 인풋 파라미터에서 와일드카드 유형을 사용하라' 라고 추천하면서 PECS 라는 연상 기호를 제안했는데, Producer-Extends, Consumer-Super 라는 뜻이다.

그럼 다음 글 부터, 코틀린은 이를 어떻게 해결하는지 살펴보자.

profile
Android Developer @kakaobank

0개의 댓글