Covariance

이미자원숭이
4 min readNov 22, 2017

원문은 여기

읽기 전 도움될 수 있는 URL이 있습니다.

객체 지향 코드를 작성하는 대부분의 프로그래머는 상속 개념에 익숙하며 Sub Class를 마치 Super Class 처럼 전달할 수 있습니다.

그러나 Generic으로 작업하기 시작할 때 하위 유형 지정 규칙이 항상 직관적인 것은 아닙니다.

What is Covariance?

공분산 (Covariance)은 두 방향 집합의 하위 집합 인 두 집합 유형 간의 관계를 설명합니다. 예를 들어 첫 번째 유형 집합의 경우 A와 B의 두 클래스가 있습니다. 여기서 B는 A의 하위 유형입니다.

open class A
open class B : A()

두번째는 두 클래스의 각각에 대한 read-only list를 고려할 것입니다.

List<A>
List<B>

AB에 대한 subtyping rules은 분명합니다.

그러나 List<A>List <B>에 대한 하위 유형 지정 규칙은 무엇입니까?

List <B>List <A>의 subtyping이입니다.

BA의 subtyping 일까요?

그렇다면 subtyping은 동일한 방향으로 가고 List는 “ covariant on its type parameter”이라고합니다.

  • Read-only List은 실제로 type parameter에서 공변 (covariant)입니다. 따라서 List <B>List <A>의 subtype입니다.
  • 그러나 MutableList는 공변 (covariant)이 아니기 때문에 MutableList <B>MutableList <A>의 subtype이 아닙니다.

Examples

List는 공변 (covariant)이기 때문에 List <A>처럼 Read-only List <B>를 전달할 수 있습니다.

공분산은 generic class에서 자동으로 발생하지 않습니다.

예를 들어, 다음은 일반적인 generic Box class입니다.

Box는 T에서 공변 (covariant)이 아니므로 컴파일이 실패합니다.

이 변수를 공변 (covariant)하게 만들려면 type parameter를 out으로 표시해야합니다.

아래 내용을 이해하는데 상당히 어려웠다. 즉, complier에게 type-safe 기능을 제공하지 않는 것을 알려주기 위하여 out을 표시한다는 내용으로 알 수 있다.

out variance annotation으로 type parameter를 표시함으로써 컴파일러에게 type 객체가 생성 된 후에는 type-safe을 제공하지 않으므로 type T의 함수 argument를 허용하지 않는다고 말합니다.

이것이 type parameter가 out으로 표시되는 이유입니다.

Covariance and Inheritance

공분산은 제네릭에만 적용되는 것은 아닙니다. 서브 클래스의 함수를 오버라이드 (override) 할 때, 슈퍼 클래스가 선언 한 것보다 더 구체적인 리턴 타입을 선언 할 수 있습니다.

이는 Kotlin (Java)의 return type이 공변 (covariant)이기 때문입니다.

--

--