지난 주 C#에 대한 질문을 받았을 때 추상 클래스, 인터페이스의 개념을 설명하던 도중 다중 상속에 관한 답변을 했다. 그때 C#은 왜 다중 상속을 기본적으로 제한했느냐 는 질문에 대답하지 못하여 공부하기 위해 정리해본다.
결론 부터 말하면 죽음의 다이아몬드 상속 때문이다.
죽음의 다이아몬드 상속이란
C++는 다중 상속이 가능한데, 클래스들이 서로 상속을 받게 되면서 다이아몬드 구조의 상속관계를 갖게 된다. 이떄 모호성이 발생하며 생기는 문제를 지칭한다.
Attack(Base상속)
, Defence(Base상속)
를 상속 받은 Player
클래스가 있다.
이때 Player 클래스에서 m_Value;
, DoIt();
을 사용하고자 하면 문제가 발생한다.
Player 클래스가 Attack
, Defence
를 상속 받게 되면 이들은 Base에서 상속받은 m_Value;
, DoIt();
을 하나씩 가지고 있기 때문에 플레이어는 같은 변수, 함수를 두 개씩 가지게 되어 어떤 것을 사용하고자 하는지 알 수가 없는 모호성 문제가 발생한다.
C++에서는 가상 상속을 통해 이 문제를 어느정도 해결이 가능하나 사용은 지양한다고 한다.
이렇게 코드를 작성하는 프로그래머 조차 어떤 동작이 실행 되는지 알 수 없는 상황을 미연에 방지하기 위해서 C#에서는 다중 상속 이슈를 제한하고 인터페이스를 통해서 틀만 제공하여 구성할 수 있도록 제한을 해두었다. 오늘도 질문을 통해 한 가지의 개념을 배워갔다. 다음에도 이어서 내가 대답하지 못한 질문들에 대해 공부해봐야겠다.
C# 에서는 Interface를 통한 다중 상속이 가능하지 않나?
C#에서 제공하는 Interface를 통하면 다중 상속을 해줄 수는 있지만 그 기능은 굉장히 제한적이다.
Interface는 어차피 함수의 이름과 같은 '틀' 밖에 제공할 수 없다. 해당 함수의 기능은 상속을 받은 부분에서 채워주어야하니 죽음의 다이아몬드와 같은 이슈가 발생하지 않는다.