다중 상속
IT 위키
더 많은 작업
다중 상속(Multiple Inheritance)은 객체지향 언어에서 한 클래스가 둘 이상의 부모 클래스로부터 속성과 메서드를 함께 물려받는 것이다.
상속은 기존 클래스를 바탕으로 새 클래스를 만드는 객체지향의 기본 기능이다(객체지향 기법). 부모가 하나면 단일 상속, 둘 이상이면 다중 상속이다. 다중 상속을 쓰면 여러 클래스의 기능을 한 클래스에 모을 수 있지만, 부모들에 같은 이름의 멤버가 있으면 어느 것을 쓸지 모호해지는 문제가 생긴다. 그래서 언어마다 다중 상속을 허용하는 정도가 다르다.
| 언어 | 클래스 다중 상속 | 대신 쓰는 방법 |
|---|---|---|
| C++ | 지원한다 | 가상 상속으로 다이아몬드 문제를 푼다 |
| 파이썬 | 지원한다 | 메서드 결정 순서(MRO, C3 선형화)로 찾을 순서를 정한다 |
| 자바, C# | 지원하지 않는다(클래스는 하나만 상속) | 인터페이스는 여러 개 구현할 수 있다 → 객체지향 인터페이스 |
클래스 이름 뒤 콜론 다음에 부모 클래스를 쉼표로 나열한다.
class Shape : public Item, public Object { // Item 과 Object 를 함께 상속
public:
virtual void group() = 0; // 순수 가상 함수
virtual void ungroup() = 0;
};
- 위
Shape는 부모가 둘이므로 다중 상속 클래스다 - 순수 가상 함수(
= 0)를 가지므로 추상 클래스이기도 하다 → 추상 클래스 - 본문 없이 이름·반환형·매개변수만 적은 선언은 멤버 함수의 원형(prototype)이다
- 부모 클래스에서 물려받는 접근 지정(public·protected·private)은 부모마다 따로 적는다
B 와 C 가 모두 A 를 상속하고, D 가 B 와 C 를 다중 상속하면 D 안에 A 의 멤버가 두 벌 생긴다. D 에서 A 의 멤버를 부르면 B 를 거친 것인지 C 를 거친 것인지 모호하다. 이것을 상속 관계 그림의 모양을 따서 다이아몬드 문제(죽음의 다이아몬드)라 한다.
A
/ \
B C
\ /
D
- C++ 은
class B : virtual public A처럼 가상 상속을 쓰면 A 를 한 벌만 두어 모호함을 없앤다 - 자바는 클래스 다중 상속을 막아 이 문제를 피하고, 구현이 없는 인터페이스만 여러 개 받게 한다(자바 8 이후 디폴트 메서드가 겹치면 직접 재정의해야 한다)
- 장점 : 여러 클래스의 기능을 재사용해 한 클래스로 모을 수 있다. 현실의 '~이면서 ~인' 관계를 그대로 표현한다
- 단점 : 이름 충돌·다이아몬드 문제로 구조가 복잡해지고, 상속 계층을 이해하기 어려워진다. 그래서 상속보다 합성(composition)을 권하는 설계 원칙이 있다