공변성과 반공변성 (컴퓨터 과학)
공변성(Covariance)과 반공변성(Contravariance)은 컴퓨터 과학, 특히 타입 이론과 프로그래밍 언어 설계에서 하위 타입 관계(subtype relationship)가 복잡한 타입(예: 함수 타입, 제네릭 타입)에 어떻게 영향을 미치는지를 설명하는 개념입니다. 간단히 말해, 타입 A가 타입 B의 하위 타입일 때, A와 B를 사용하여 만들어진 다른 타입 간의 하위 타입 관계가 어떻게 결정되는지를 나타냅니다. 이는 객체 지향 프로그래밍에서 다형성(polymorphism)을 구현하고 타입 안전성을 유지하는 데 중요한 역할을 합니다.
정의:
-
공변성(Covariance): 만약
A
가B
의 하위 타입이라면,Container<A>
가Container<B>
의 하위 타입이 되는 성질을 말합니다. 즉, 컨테이너의 타입 인자가 하위 타입 관계를 "유지"하는 것입니다. 예를 들어,Dog
가Animal
의 하위 타입이라면,List<Dog>
는List<Animal>
의 하위 타입이 됩니다. -
반공변성(Contravariance): 만약
A
가B
의 하위 타입이라면,Container<B>
가Container<A>
의 하위 타입이 되는 성질을 말합니다. 즉, 컨테이너의 타입 인자가 하위 타입 관계를 "반전"시키는 것입니다. 이는 주로 함수 타입에서 나타납니다. 예를 들어,Function<Animal, void>
(Animal을 인자로 받아 void를 반환하는 함수)는Function<Dog, void>
(Dog를 인자로 받아 void를 반환하는 함수)의 하위 타입입니다. 왜냐하면Function<Animal, void>
는Dog
객체를 인자로 받아도 안전하게 동작할 수 있기 때문입니다. -
무공변성(Invariance):
A
가B
의 하위 타입이라 할지라도Container<A>
와Container<B>
사이에 하위 타입 관계가 없는 경우를 말합니다. 즉, 타입 인자의 하위 타입 관계가 컨테이너 타입에 영향을 미치지 않습니다.
함수 타입에서의 공변성과 반공변성:
함수 타입 A -> B
(A를 인자로 받아 B를 반환하는 함수)에서, 인자 타입은 반공변적이고 반환 타입은 공변적입니다.
- 인자 타입 (반공변성):
A1
이A2
의 상위 타입(supertype)이면,(A2 -> B)
는(A1 -> B)
의 하위 타입입니다. - 반환 타입 (공변성):
B1
이B2
의 하위 타입이면,(A -> B1)
은(A -> B2)
의 하위 타입입니다.
예시 (Java):
class Animal {}
class Dog extends Animal {}
// 공변성: Dog가 Animal의 하위 타입이므로, List<Dog>는 List<Animal>에 할당할 수 없습니다 (Java 제네릭은 기본적으로 무공변성을 가짐).
// List<Animal> animals = new ArrayList<Dog>(); // 컴파일 에러
// 반공변성 (와일드카드와 함께 사용):
public void feedAnimals(List<? super Dog> animals) {
animals.add(new Dog()); // Dog 또는 Animal 객체를 안전하게 추가할 수 있습니다.
}
중요성:
공변성과 반공변성은 타입 시스템의 안전성을 보장하고 다형성을 효과적으로 활용하는 데 필수적입니다. 이러한 개념을 이해하면 더욱 유연하고 강력한 코드를 작성할 수 있으며, 컴파일 시점에 많은 타입 에러를 방지할 수 있습니다. 특히, 제네릭 프로그래밍과 함수형 프로그래밍에서 중요한 역할을 합니다.