최신판 |
당신의 편집 |
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#]]
| |
− | * [[인터페이스]]
| |
− | | |
− | {{프로그래밍|검토 필요}}
| |