원문은 여기
읽기 전 도움될 수 있는 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>
A
와 B
에 대한 subtyping rules은 분명합니다.
그러나 List<A>
및 List <B>
에 대한 하위 유형 지정 규칙은 무엇입니까?
List <B>
는 List <A>
의 subtyping이입니다.
B
는 A
의 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)이기 때문입니다.