Java 및 C #에서는 다중 상속이 허용되지 않는다는 것을 알고 있습니다. 많은 책에서는 다중 상속이 허용되지 않는다고 말합니다. 그러나 인터페이스를 사용하여 구현할 수 있습니다. 허용되지 않는 이유에 대해서는 논의되지 않습니다. 아무도 그것이 허용되지 않는 이유를 정확하게 말할 수 있습니까?
답변
짧은 대답은 언어 디자이너가하지 않기로 결정했기 때문입니다.
기본적으로 .NET 및 Java 디자이너 모두 MI를 추가 하면 언어 에 너무 많은 복잡성 이 추가 되는 반면 너무 적은 이점 을 제공 한다고 생각했기 때문에 다중 상속을 허용하지 않는 것 같습니다 .
좀 더 재미 있고 깊이있게 읽을 수 있도록 웹에서 일부 언어 디자이너의 인터뷰와 함께 사용할 수있는 기사가 있습니다. 예를 들어, .NET의 경우, CLR 관련 MS에서 일한 Chris Brumme는 다음과 같은 이유를 설명했습니다.
서로 다른 언어는 실제로 MI 작동 방식에 대해 서로 다른 기대치를 가지고 있습니다. 예를 들어, 충돌이 해결되는 방법과 중복 기반이 병합 또는 중복되는지 여부가 있습니다. CLR에서 MI를 구현하기 전에 모든 언어를 조사하고 공통 개념을 파악하고 언어 중립적 인 방식으로 표현하는 방법을 결정해야합니다. 또한 MI가 CLS에 속하는지 여부와이 개념을 원하지 않는 언어 (예 : VB.NET)에서 이것이 의미하는 바를 결정해야합니다. 물론 이것이 우리가 공통 언어 런타임으로하고있는 사업이지만 아직 MI를 위해 수행하지는 않았습니다.
MI가 진정으로 적절한 곳의 수는 실제로 매우 적습니다. 대부분의 경우 다중 인터페이스 상속이 대신 작업을 수행 할 수 있습니다. 다른 경우에는 캡슐화 및 위임을 사용할 수 있습니다. 믹스 인과 같은 약간 다른 구조를 추가하면 실제로 더 강력할까요?
다중 구현 상속은 구현에 많은 복잡성을 주입합니다. 이러한 복잡성은 캐스팅, 레이아웃, 디스패치, 필드 액세스, 직렬화, ID 비교, 검증 가능성, 반사, 제네릭 및 기타 여러 장소에 영향을 미칩니다.
Java의 경우 다음 기사를 읽을 수 있습니다 .
Java 언어에서 다중 상속을 생략하는 이유는 대부분 “단순하고 객체 지향적이며 친숙한”목표에서 비롯됩니다. 단순한 언어로서 Java의 제작자는 대부분의 개발자가 광범위한 교육없이 이해할 수있는 언어를 원했습니다. 이를 위해 그들은 C ++의 불필요한 복잡성 (단순함)을 넘기지 않고 가능한 한 C ++와 유사한 언어 (익숙한)를 만들기 위해 노력했습니다.
디자이너의 의견으로는 다중 상속은 해결하는 것보다 더 많은 문제와 혼란을 야기합니다. 그래서 그들은 (연산자 과부하를 줄이는 것처럼) 언어에서 다중 상속을 자릅니다. 디자이너의 광범위한 C ++ 경험을 통해 다중 상속은 골칫거리가 아니라는 사실을 알게되었습니다.
답변
구현의 다중 상속은 허용되지 않습니다.
문제는 컴파일러 / 런타임이 Draw () 메서드에 대한 구현이있는 Cowboy 및 Artist 클래스가있는 경우 수행 할 작업을 파악할 수 없다는 것입니다. 그런 다음 새 CowboyArtist 형식을 만들려고합니다. draw () 메서드를 호출하면 어떻게됩니까? 누군가가 거리에서 죽어 있나요, 아니면 아름다운 수채화가 있나요?
이중 다이아몬드 상속 문제라고 생각합니다.
답변
이유 :
Java는 단순성 때문에 매우 인기 있고 코딩하기 쉽습니다.
그래서 자바 개발자들은 프로그래머가 이해하기 어렵고 복잡하다고 느끼는 것을 피하려고 노력했습니다. 이러한 종류의 속성 중 하나는 다중 상속입니다.
- 그들은 포인터를 피했습니다.
- 그들은 다중 상속을 피했습니다.
다중 상속 문제 : 다이아몬드 문제.
예 :
- 클래스 A에 fun () 메서드가 있다고 가정합니다. 클래스 B와 클래스 C는 클래스 A에서 파생됩니다.
- 클래스 B와 C는 모두 fun () 메서드를 재정의합니다.
- 이제 클래스 D가 클래스 B와 C를 모두 상속한다고 가정합니다 (가정 만 해당).
- 클래스 D에 대한 개체를 만듭니다.
- D d = 새로운 D ();
- d.fun (); 액세스를 시도하십시오. => 클래스 B의 fun () 또는 클래스 C의 fun ()을 호출할까요?
이것은 다이아몬드 문제에 존재하는 모호성입니다.
이 문제를 해결하는 것은 불가능하지 않지만, 읽는 동안 프로그래머에게 더 많은 혼란과 복잡성을 야기합니다.
해결하려고하는 것보다 더 많은 문제를 일으 킵니다.
참고 : 그러나 어떤 방법 으로든 인터페이스를 사용하여 항상 간접적으로 다중 상속을 구현할 수 있습니다.
답변
Java는 C ++와 크게 다른 디자인 철학을 가지고 있기 때문입니다. (여기서 C #은 논의하지 않겠습니다.)
C ++를 설계 할 때 Stroustrup은 어떻게 오용 될 수 있는지에 관계없이 유용한 기능을 포함하기를 원했습니다. 다중 상속, 연산자 오버로딩, 템플릿 및 기타 다양한 기능을 사용하여 큰 시간을 낭비 할 수 있지만이를 사용하여 아주 좋은 작업을 수행 할 수도 있습니다.
Java 디자인 철학은 언어 구조의 안전성을 강조하는 것입니다. 그 결과 훨씬 더 어색한 일이 있지만,보고있는 코드가 자신이 생각하는 일을 의미한다는 사실을 훨씬 더 확신 할 수 있습니다.
게다가 자바는 가장 잘 알려진 OO 언어 인 C ++와 스몰 토크의 반응이었다. MI를 더 잘 처리하는 다른 OO 시스템과 함께 많은 다른 OO 언어 (Common Lisp가 실제로 표준화 된 첫 번째 언어)가 있습니다.
인터페이스, 구성 및 위임을 사용하여 Java에서 MI를 수행하는 것이 전적으로 가능하다는 것은 말할 것도 없습니다. C ++보다 더 명시 적이므로 사용하기 어색하지만 언뜻보기에 이해하기 쉬운 내용을 얻을 수 있습니다.
여기에는 정답이 없습니다. 다양한 답변이 있으며 주어진 상황에 대해 어느 것이 더 나은지는 응용 프로그램과 개인의 선호도에 따라 다릅니다.
답변
사람들이 MI에서 멀어지는 주된 이유는 (유일한 것은 아니지만) 구현의 모호성을 유발하는 소위 “다이아몬드 문제”입니다. 이 위키피디아 기사 는 그것에 대해 논의하고 내가 할 수있는 것보다 더 잘 설명합니다. MI는 또한 더 복잡한 코드로 이어질 수 있으며 많은 OO 디자이너는 MI가 필요하지 않다고 주장하며 MI를 사용하면 모델이 잘못되었을 수 있습니다. 이 마지막 요점에 동의하는지 잘 모르겠지만 단순하게 유지하는 것은 항상 좋은 계획입니다.
답변
C ++에서 다중 상속은 부적절하게 사용될 때 큰 골칫거리였습니다. 이러한 인기있는 디자인 문제를 피하기 위해 대신 현대 언어 (java, C #)에서 여러 인터페이스 “상속”이 강제되었습니다.
답변
다중 상속은
- 이해하기 어렵다
- 디버그하기 어려움 (예를 들어, 동일한 이름의 메서드가있는 여러 프레임 워크의 클래스를 깊게 혼합하면 예상치 못한 시너지가 발생할 수 있음)
- 오용하기 쉽다
- 정말로 그 유용
- 특히 정확 하고 효율적으로 수행하려는 경우 구현하기가 어렵습니다.
따라서 Java 언어에 다중 상속을 포함 하지 않는 것이 현명한 선택으로 간주 될 수 있습니다 .