나는 언어에서 다중 상속을 지원한다는 아이디어를 항상 좋아했습니다. 대부분의 경우 의도적으로 무시되었지만 "교체"라고 생각되는 것은 인터페이스입니다. 인터페이스는 단순히 다중 상속이 수행하는 모든 동일한 접지를 다루지 않으며, 이러한 제한으로 인해 더 많은 상용구 코드가 생길 수 있습니다.
내가 들어 본 유일한 기본 이유는 기본 클래스 의 다이아몬드 문제 입니다. 나는 그것을 받아 들일 수 없다. 나에게, 그것은 엄청 많이처럼, "음, 그건 벗기 수 를 망치는, 그래서 자동으로 나쁜 생각입니다." 그래도 프로그래밍 언어로 무엇이든 망칠 수 있습니다. 적어도 더 철저한 설명 없이는 이것을 심각하게 받아 들일 수 없습니다.
이 문제를 알고 있다는 것은 전투의 90 %입니다. 또한 몇 년 전 "봉투"알고리즘 또는 이와 유사한 것 (이 링이 종을 울리는가?)과 관련된 일반적인 해결 방법에 대해 들었습니다.
다이아몬드 문제와 관련하여 내가 생각할 수있는 유일한 잠재적 문제는 타사 라이브러리를 사용하려고하는데 해당 라이브러리에서 관련이없는 것으로 보이는 두 개의 클래스가 공통 기본 클래스를 가지고 있음을 알 수없는 경우입니다. 예를 들어, 간단한 언어 기능인 문서는 실제로 다이아몬드를 컴파일하기 전에 다이아몬드를 만들려는 의도를 명시 적으로 요구할 수 있습니다. 그러한 특징으로, 다이아몬드의 생성은 의도적이거나 무모하거나이 함정을 알지 못하기 때문입니다.
모든 사람들이 말하기를 ... 대부분의 사람들이 여러 상속을 싫어하는 실제적인 이유 가 있습니까? 아니면 모두 좋은 것보다 더 많은 해를 입히는 히스테리입니까? 여기에 보이지 않는 것이 있습니까? 감사합니다.
예
자동차는 바퀴 달린 차량, KIASpectra는 자동차 및 전자, KIASpectra는 라디오를 확장합니다. KIASpectra에 전자 제품이 포함되지 않은 이유는 무엇입니까?
전자 이기 때문 입니다 . 상속 대 구성은 항상 is-a 관계 대 has-a 관계 여야합니다.
전자 이기 때문 입니다 . 와이어, 회로 보드, 스위치 등이 모두 위와 아래에 있습니다.
전자 이기 때문 입니다 . 겨울에 배터리가 방전 되면 모든 바퀴가 갑자기 빠진 것처럼 큰 어려움에 처하게됩니다.
왜 인터페이스를 사용하지 않습니까? 예를 들어 3 번을 봅시다. 나는 다시이 이상을 쓰고 싶지 않아, 난 정말 이 하나를 수행하는 몇 가지 기괴한 프록시 도우미 클래스를 만들려하지 않습니다
private void runOrDont()
{
if (this.battery)
{
if (this.battery.working && this.switchedOn)
{
this.run();
return;
}
}
this.dontRun();
}
(우리는 그 구현이 좋은지 나쁜지를 알지 못합니다.) WheeledVehicle의 어떤 것과도 관련이없는 Electronic과 관련된 이러한 기능 중 일부 가 어떻게 존재할지 상상할 수 있습니다 .
거기에 해석의 여지가 있기 때문에 그 예를 정할 것인지 확실하지 않았습니다. 비행기 확장 차량 및 FlyingObject 및 Bird 확장 Animal 및 FlyingObject 또는 훨씬 더 순수한 예를 생각할 수도 있습니다.
Traits
-옵션으로 구현 된 인터페이스처럼 작동하지만 다이아몬드 문제와 같은 문제를 방지하는 데 도움이되는 몇 가지 제한 사항이 있습니다.
KiaSpectra
하지 는 Electronic
; 그것은 전자 제품 을 가지고 있으며 ElectronicCar
(확장 될 것입니다 Car
)