검수요청.png검수요청.png

"다중상속"의 두 판 사이의 차이

위키원
이동: 둘러보기, 검색
잔글
 
(사용자 2명의 중간 판 20개는 보이지 않습니다)
1번째 줄: 1번째 줄:
'''다중상속'''(multiple inheritance)은 [[객체 지향 프로그래밍]]에서 한 [[클래스]]가 한 번에 두 개 이상의 클래스를 상속받는 경우를 말한다. 다중상속을 받은 클래스의 경우 두 개 이상의 부모 클래스를 가지게 된다.
+
'''다중상속'''<!--다중 상속-->(multiple inheritance)은 [[객체 지향 프로그래밍]]에서 한 [[클래스]]가 한 번에 두 개 이상의 클래스를 [[상속 (프로그래밍)|상속]]받는 경우를 말한다. 다중상속을 받은 [[클래스]]의 경우 두 개 이상의 부모 클래스를 가지게 된다.
 +
 
 +
== 개요 ==
 +
다중상속(multiple inheritance)이란 [[객체 지향 프로그래밍]]의 특징 중 하나이며, 어떤 클래스가 하나 이상의 상위 클래스로부터 여러 가지 행동이나 특징을 [[상속 (프로그래밍)|상속]]받을 수 있는 것을 말한다. 다중상속을 허용하면 여러 클래스로부터 상속 받을 수 있기 때문에 복합적인 기능을 가진 클래스를 쉽게 작성할 수 있지만 프로그래밍을 복잡하게 만들 수 있기 때문에 실용성이 떨어진다.<ref name="자료1"> 힘껏 날아 오르자!, 〈[http://blog.daum.net/dsmcj/37 다중상속과 단일상속의 장단점]〉, 《개인블로그》, 2009-03-11</ref>
 +
 
 +
== 특징 ==
 +
다중 상속을 지원하게 되면 하나 이상의 상위 클래스로부터 여러가지 특징을 상속 받을 수 있다. 하지만 이러한 장점 때문에 상속 구조에 문제가 생겨 오히려 프로그래밍을 복잡하게 만들 수 있다는 특징을 가지고 있다.
 +
 
 +
===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에서 함수를 사용할 때 아래와 같이 작성이 되어 모호성이 발생한다.<ref name="자료2"> Pac, 〈[https://pacs.tistory.com/entry/C-%EC%83%81%EC%86%8D%EC%9D%98-%EB%A7%88%EC%A7%80%EB%A7%89-%EB%8B%A4%EC%A4%91-%EC%83%81%EC%86%8DMultiple-Inheritance 상속의 마지막, 다중 상속(Multiple Inheritance)]〉, 《개인블로그》, 2010-09-17</ref>
 +
 
 +
class C : public A, public B{
 +
    public:
 +
        void sampleC(){
 +
            sample(); //A클래스의 sample
 +
            sample(); //B클래스의 sample
 +
        }
 +
};
 +
 
 +
위와 같은 모호성 때문에 생기는 문제를 다이아몬드 문제라고 하는데 이는 구조가 다이아몬드 형태를 띄우고 있어 붙여진 이름이다.
 +
 
 +
===다이아몬드 문제===
 +
 
 +
[[파일:다중상속문제.PNG | 500픽셀]]
 +
 
 +
위의 클래스 다이어그램과 같은 [[상속 (프로그래밍)|상속]] 구조에서 발생되는 문제가 다이아몬드 문제이다. Grand라는 클래스에서 example이라는 [[메소드]]를 가질 때 상속을 받은 ParentsA와 ParentsB에서는 example이라는 메소드를 [[오버라이딩]]한다. 이 때 son에서 example이라는 메소드를 불러올 때 어떤 부모의 메소드를 불러와야 하는지 모호해져서 충돌이 생기게 된다. 이를 다이아몬드 문제라고 하는데 [[자바]]에서는 이러한 문제를 사전에 방지하기 위해서 다중 상속을 지원하지 않는다.
 +
 
 +
===자바===
 +
[[자바]]는 다이아몬드 문제를 방지하기 위해 다중 상속을 지원하지 않는다. 하지만 이런 문제가 있음에도 불구하고 [[인터페이스]]를 통해 다중상속의 기능을 사용할 수 있다.
 +
인터페이스를 이용한 다중 상속은 실제로 구현했을 때 아무런 문제를 발생시키지 않는다. 그 이유는 인터페이스의 기능 때문이다. 인터페이스는 [[메소드]]의 기능에 대해 선언만 해두기 때문에 다이아몬드 상속이 되더라도 충돌할 여지가 없다.<ref name="자료3"> 사용자 siyoon210, 〈[https://siyoon210.tistory.com/125 자바는 왜 다중상속을 지원하지 않을까? (다이아몬드 문제)]〉, 《개인블로그》, 2019-02-24</ref>
 +
 
 +
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를 활용해 다중 상속이 가능하다.
 +
 
 +
===파이썬===
 +
파이썬에서 다중 상속을 받기 위해서는 'class 클래스이름(부모클래스이름1, 부모클래스이름2): 코드' 형식을 사용한다. 여러 클래스로부터 상속을 받을 때 괄호 안에 클래스 이름을 콤마(,)로 구분해서 넣는다.
 +
 
 +
class 클래스이름1:
 +
    코드
 +
class 클래스이름2:
 +
    코드
 +
class 클래스이름3(클래스이름1, 클래스이름2):
 +
    코드
 +
 
 +
많은 프로그래밍 언어들이 다이아몬드 문제에 대한 해결책을 제시하고 있는데 파이썬에서는 메서드 탐색 순서를 따른다. 파이썬은 다중 상속을 할 때 상속 클래스 목록 중 왼쪽에서 오른쪽 순서로 메서드를 찾는다. 그러므로 같은 메서드가 있다면 왼쪽에 있는 클래스 내의 메서드를 우선으로 한다. 만약 상속관계가 복잡하게 얽혀있다면 MRO 메서도를 사용해 살펴보는것이 편리하다.<ref name="자료5"> 코딩도장, 〈[https://dojang.io/mod/page/view.php?id=2388 다중 상속 사용하기]〉, 《코딩도장》</ref>
 +
 
 +
===C#===
 +
C#에서 클래스는 여러 클래스를 동시에 상속하는 다중상속이 불가능하다.<ref name="자료6"> 셩님, 〈[https://debuglog.tistory.com/134 인터페이스 다중 상속]〉, 《개인블로그》, 2018-06-18</ref> 하지만 자바와 같이 인터페이스를 활용한 다중 상속은 가능하다.
 +
 
 +
interface A{
 +
    void sampleA();
 +
}
 +
 +
interface B{
 +
    void sampleB();
 +
}
 +
 
 +
class C : A, B
 +
{
 +
    void sampleA(){
 +
          코드
 +
    }
 +
    void sampleB(){
 +
          코드
 +
    }
 +
}
 +
 
 +
위와 같이 인터페이스를 사용하면 다중 상속이 가능하다. 이 때 클래스 하나와 여러 인터페이스를 상속 받는 것 또한 가능하다. 하지만 클래스가 여러개 들어가는 것은 사용할 수 없다.
 +
 
 +
class A{
 +
    void sampleA();
 +
}
 +
 +
interface B{
 +
    void sampleB();
 +
}
 +
 
 +
class C : A, B
 +
{
 +
    void sampleA(){
 +
          코드
 +
    }
 +
    void sampleB(){
 +
          코드
 +
    }
 +
}
 +
 
 +
===문제점===
 +
다중 상속의 문제점은 크게 두가지가 있다. 첫 번째 문제는 [[변수]]의 모호함 때문에 구현을 막아놓은 것이다. 각 부모클래스의 똑같은 이름의 [[속성]], [[메소드]]를 가진 상황이 있다고 가정하면 그 변수, 메소드가 어느 부모를 상속하여 받아서 사용되는 지를 그 자체를 이해하지 못하기 때문이다.
 +
그리고 두 번째 문제로는 상속 기능의 무거움이다. 실무에서 사용할 때 [[객체 지향 프로그래밍]]은 속성이 1개에서 10개로 끝나지 않고 다루는 메소드만 해도 수없이 많다. 이렇게 많은 속성들을 다중으로 상속을 받는다면 프로그램 자체에 큰 부담을 줄 수 있다.
 +
 
 +
[[C++]]에서는 이름 공간이라는 기능을 이용해서 데이터의 모호함을 구별 할 수 있게 해 두었다. 그리고 [[상속 (프로그래밍)|상속]]의 경우가 아닌 [[메소드]]만 상속을 받아와서 속성 값을 제어할 수 있는 [[인터페이스]]라는 기능을 만들었다. 하지만 인터페이스 기능을 사용하기 위해서는 반드시 메소드의 구현을 해야한다.
 +
 
 +
이렇게 문제점을 극복할 수 있는 기능들이 있지만 기업간의 협업과 유지보수에서 코드의 모호함으로 인해 어려움을 격기 때문에 다중 상속을 잘 사용하지 않게 되었다.<ref name="자료4"> 김형수, 〈[https://m.blog.naver.com/PostView.nhn?blogId=there924&logNo=220857891926&proxyReferer=https%3A%2F%2Fwww.google.com%2F 객체지향(6) - 다중상속]〉, 《개인블로그》, 2016-11-10</ref>
 +
 
 +
{{각주}}
 +
 
 +
==참고자료==
 +
* 힘껏 날아 오르자!, 〈[http://blog.daum.net/dsmcj/37 다중상속과 단일상속의 장단점]〉, 《개인블로그》, 2009-03-11
 +
* Pac, 〈[https://pacs.tistory.com/entry/C-%EC%83%81%EC%86%8D%EC%9D%98-%EB%A7%88%EC%A7%80%EB%A7%89-%EB%8B%A4%EC%A4%91-%EC%83%81%EC%86%8DMultiple-Inheritance 상속의 마지막, 다중 상속(Multiple Inheritance)]〉, 《개인블로그》, 2010-09-17
 +
* 사용자 siyoon210, 〈[https://siyoon210.tistory.com/125 자바는 왜 다중상속을 지원하지 않을까? (다이아몬드 문제)]〉, 《개인블로그》, 2019-02-24
 +
* 김형수, 〈[https://m.blog.naver.com/PostView.nhn?blogId=there924&logNo=220857891926&proxyReferer=https%3A%2F%2Fwww.google.com%2F 객체지향(6) - 다중상속]〉, 《개인블로그》, 2016-11-10
 +
* 코딩도장, 〈[https://dojang.io/mod/page/view.php?id=2388 다중 상속 사용하기]〉, 《코딩도장》
 +
* 셩님, 〈[https://debuglog.tistory.com/134 인터페이스 다중 상속]〉, 《개인블로그》, 2018-06-18
  
 
== 같이 보기 ==
 
== 같이 보기 ==
 
* [[객체 지향 프로그래밍]]
 
* [[객체 지향 프로그래밍]]
 
* [[클래스]]
 
* [[클래스]]
* [[상속]]
+
* [[상속 (프로그래밍)|상속]]
 +
* [[메소드]]
 +
* [[오버라이딩]]
 +
* [[자바]]
 +
* [[C++]]
 +
* [[파이썬]]
 +
* [[C#]]
 +
* [[인터페이스]]
  
[[분류:프로그램]]
+
{{프로그래밍|검토 필요}}

2022년 1월 31일 (월) 23:35 기준 최신판

다중상속(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를 활용해 다중 상속이 가능하다.

파이썬[편집]

파이썬에서 다중 상속을 받기 위해서는 'class 클래스이름(부모클래스이름1, 부모클래스이름2): 코드' 형식을 사용한다. 여러 클래스로부터 상속을 받을 때 괄호 안에 클래스 이름을 콤마(,)로 구분해서 넣는다.

class 클래스이름1:
    코드
class 클래스이름2:
    코드
class 클래스이름3(클래스이름1, 클래스이름2):
    코드

많은 프로그래밍 언어들이 다이아몬드 문제에 대한 해결책을 제시하고 있는데 파이썬에서는 메서드 탐색 순서를 따른다. 파이썬은 다중 상속을 할 때 상속 클래스 목록 중 왼쪽에서 오른쪽 순서로 메서드를 찾는다. 그러므로 같은 메서드가 있다면 왼쪽에 있는 클래스 내의 메서드를 우선으로 한다. 만약 상속관계가 복잡하게 얽혀있다면 MRO 메서도를 사용해 살펴보는것이 편리하다.[4]

C#[편집]

C#에서 클래스는 여러 클래스를 동시에 상속하는 다중상속이 불가능하다.[5] 하지만 자바와 같이 인터페이스를 활용한 다중 상속은 가능하다.

interface A{
    void sampleA();
}

interface B{
    void sampleB();
}
class C : A, B
{
    void sampleA(){
         코드
    }
    void sampleB(){
         코드
    }
}

위와 같이 인터페이스를 사용하면 다중 상속이 가능하다. 이 때 클래스 하나와 여러 인터페이스를 상속 받는 것 또한 가능하다. 하지만 클래스가 여러개 들어가는 것은 사용할 수 없다.

class A{
    void sampleA();
}

interface B{
    void sampleB();
}
class C : A, B
{
    void sampleA(){
         코드
    }
    void sampleB(){
         코드
    }
}

문제점[편집]

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

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

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

각주[편집]

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

참고자료[편집]

같이 보기[편집]


  검수요청.png검수요청.png 이 다중상속 문서는 프로그래밍에 관한 글로서 검토가 필요합니다. 위키 문서는 누구든지 자유롭게 편집할 수 있습니다. [편집]을 눌러 문서 내용을 검토·수정해 주세요.