의견.png

다중상속

위키원
rudgh01 (토론 | 기여)님의 2020년 8월 31일 (월) 16:56 판 (다이아몬드 문제)
이동: 둘러보기, 검색

다중상속(multiple inheritance)은 객체 지향 프로그래밍에서 한 클래스가 한 번에 두 개 이상의 클래스를 상속받는 경우를 말한다. 다중상속을 받은 클래스의 경우 두 개 이상의 부모 클래스를 가지게 된다.

개 요

다중상속(Multiple inheritance)이란 객체 지향 프로그래밍의 특징 중 하나이며, 어떤 클래스가 하나 이상의 상위 클래스로부터 여러 가지 행동이나 특징을 속받을 수 있는 것을 말한다. 다중상속을 허용하면 여러 클래스로부터 상속 받을 수 있기 때문에 복합적인 기능을 가진 클래스를 쉽게 작성할 수 있지만 프로그래밍을 복잡하게 만들 수 있기 때문에 실용성이 떨어진다.[1]

특 징

다중 상속을 지원하게 되면 하나 이상의 상위 클래스로부터 여러가지 특징을 상속 받을 수 있다. 하지만 이러한 장점 때문에 상속 구조에 문제가 생겨 오히려 프로그래밍을 복잡하게 만들 수 있다는 특징을 가지고 있다.

C++

단일 상속과는 다르게 두 개 이상의 클래스를 하나가 동시에 상속받는 것으로 클래스를 선언할 때 클래스명 옆 : 연산자 뒤에 여러 개의 클래스를 콤마(,)로 나열한다.

class A{
   public:
       void sampleA(){
           cout<<"A : example"<<endl;
       }
};

class B{
   public:
       void sampleB(){
           cout<<"B : example"<<endl;
       }
};

class C : public A, public B{
   public:
       void sampleC(){
            sampleA();
            sampleB();
       }
};

int main(){
      C exampleC;
      exampleC.sampleC();
      
      return 0;
}

클래스 C에서 A와 B 클래스를 상속 받았다. 이 때 두 개 이상의 클래스를 동시에 상속받은 C는 다중 상속을 받았다고 하며 클래스A와 클래스B가 가지고 있는 속성들을 사용할 수 있다.

이 때 클래스A의 sampleA 함수와 클래스B의 sampleB 함수가 sample이라는 함수로 정의되어 있을 때 클래스 C에서 함수를 사용할 때 아래와 같이 작성이 되어 모호성이 발생한다.[2]

class C : public A, public B{
   public:
       void sampleC(){
            sample(); //A클래스의 sample
            sample(); //B클래스의 sample
       }
};

위와 같은 모호성 때문에 생기는 문제를 다이아몬드 문제라고 하는데 이는 구조가 다이아몬드 형태를 띄우고 있어 붙여진 이름이다.

다이아몬드 문제

다중상속문제.PNG

위의 클래스 다이어그램과 같은 상속 구조에서 발생되는 문제가 다이아몬드 문제이다. Grand라는 클래스에서 example이라는 메소드를 가질 때 상속을 받은 ParentsA와 ParentsB에서는 example이라는 메소드를 오버라이딩한다. 이 때 son에서 example이라는 메소드를 불러올 때 어떤 부모의 메소드를 불러와야 하는지 모호해져서 충돌이 생기게 된다. 이를 다이아몬드 문제라고 하는데 자바에서는 이러한 문제를 사전에 방지하기 위해서 다중 상속을 지원하지 않는다.

자바

자바는 다이아몬드 문제를 방지하기 위해 다중 상속을 지원하지 않는다. 하지만 이런 문제가 있음에도 불구하고 인터페이스를 통해 다중상속의 기능을 사용 할 수 있다. 인터페이스를 이용한 다중 상속은 실제로 구현했을 때 아무런 문제를 발생시키지 않는다. 그 이유는 인터페이스의 기능 때문이다. 인터페이스는 메소드의 기능에 대해 선언만 해두기 때문에 다이아몬드 상속이 되더라도 충돌할 여지가 없다.[3]

interface Grand {
     void example();
}

interface ParentsA extends Grand {
     @Override
     void example();
}

interface ParentsB extends Grand {
     @Override
     void example();
}

interface son extends ParentsA, ParentsB {
     @Override
     void example();
}

위와 같이 인터페이스에 선언을 하여 extends를 활용해 다중 상속이 가능하다.

문제점

다중 상속의 문제점은 크게 두가지가 있다. 첫 번째 문제는 변수의 모호함 때문에 구현을 막아놓은 것이다. 각 부모클래스의 똑같은 이름의 속성, 메소드를 가진 상황이 있다고 가정하면 그 변수, 메소드가 어느 부모를 상속하여 받아서 사용되는 지를 그 자체를 이해하지 못하기 때문이다. 그리고 두 번째 문제로는 상속 기능의 무거움이다. 실무에서 사용할 때 객체 지향 프로그래밍은 속성이 1개에서 10개로 끝나지 않고 다루는 메소드만 해도 수없이 많다. 이렇게 많은 속성들을 다중으로 상속을 받는다면 프로그램 자체에 큰 부담을 줄 수 있다.

C++에서는 이름 공간이라는 기능을 이용해서 데이터의 모호함을 구별 할 수 있게 해 두었다. 그리고 상속의 경우가 아닌 메소드만 상속을 받아와서 속성 값을 제어할 수 있는 인터페이스라는 기능을 만들었다. 하지만 인터페이스 기능을 사용하기 위해서는 반드시 메소드의 구현을 해야한다.

이렇게 문제점을 극복할 수 있는 기능들이 있지만 기업간의 협업과 유지보수에서 코드의 모호함으로 인해 어려움을 격기 때문에 다중 상속을 잘 사용하지 않게 되었다.[4]

각주

  1. 힘껏 날아 오르자!, 〈다중상속과 단일상속의 장단점〉, 《개인블로그》, 2009-03-11
  2. Pac, 〈상속의 마지막, 다중 상속(Multiple Inheritance)〉, 《개인블로그》, 2010-09-17
  3. 사용자 siyoon210, 〈자바는 왜 다중상속을 지원하지 않을까? (다이아몬드 문제)〉, 《개인블로그》, 2019-02-24
  4. 김형수, 〈객체지향(6) - 다중상속〉, 《개인블로그》, 2016-11-10

참고 자료

같이 보기


  의견.png 이 다중상속 문서는 프로그래밍에 관한 토막글입니다. 위키 문서는 누구든지 자유롭게 편집할 수 있습니다. [편집]을 눌러 이 문서의 내용을 채워주세요.