이 질문에는 이미 답변이 있습니다.
상속에 대한 컴포지션 우선 순위 지정
매우 인기있는 문구입니다. 나는 몇몇 기사를 읽고 각 기사는 끝에 말한다
클래스 사이에 순수한 IS-A 관계가있을 때 상속을 사용하십시오.
의 예이 기사:
여기에사과과과일명확한 IS-A 관계, 즉 Apple IS-A Fruit이 있지만, 저작자는 상속을 통해 구현 될 때 함정을 표시하는 Apple HAS-A Fruit (구성)으로 표시했습니다.
나는 여기서 다소 혼란스러워졌다. 성명서의 의미는 무엇인가?
클래스 사이에 순수한 IS-A 관계가있을 때 상속을 사용하십시오.
상속에 비해 컴포지션을 사용한다는 것은 항상시험작곡을 적용하다설사순수한 IS-A 관계가 있고 상속을 떠난다.구성이 이해가 안되는 경우에만?
상속을 사용하여 메소드를 재정의하고 다른 다형성 비헤이비어를 정의하는 대신 슈퍼 클래스의 코드를 재사용 할 때 상속 대신 컴포지션을 사용해야한다는 표시가됩니다.
그만큼java.util.Properties클래스는 상속의 나쁜 사용의 좋은 예입니다. 오히려~을 사용하여그 property를 포함하는 Hashtable확장하다메소드를 재사용하고 위임을 사용하여 메소드 일부를 다시 구현하는 것을 피하기 위해 Hashtable.
java.util.Properties확장HashTable그 결과 디자인에 부정적인 영향을 미쳤습니다. Liskov Substitution Principle에 대해 생각해 보았지만 문제라고 생각하지 않습니다. 이론적으로는 성능 / 메모리 이유로 인해 저장 (해싱) 메커니즘을 변경할 수 있지만 상속으로는 불가능하며 구성이 가능할 수 있습니다. - FuhrmanatorProperties확장Hashtable사례 단지 상속의 나쁜 사용의 좋은 예입니다.Properties전체를 신경 쓰지 말아야한다.Hashtable특정 로직과 그것의 작은 하위 세트 만 필요하므로 확장되어서는 안됩니다Hashtable, 그것 때문에~이다.하나도 아니야.용도하나? - SantiBailors
나는 이것이 객체 지향 디자인에서 가장 논의 된 부분 중 하나라고 생각한다. 이 기사에서 제안한 것처럼 구성은 상속보다 항상 선호됩니다. 그렇다고 상속을 절대로 사용해서는 안된다는 의미는 아닙니다. 당신은 그것이 더 이해하기 쉬운 곳이어야합니다 (그것은 논쟁의 여지가 있습니다).
컴포지션을 사용하면 여러 가지 장점이 있습니다. 그 중 몇 가지는 다음과 같습니다.
이 기사에는 그러한 문구가 없습니다.
use inheritance when there is pure IS-A relationship between classes
또한 Google은 귀하의 게시물을 제외한 다른 곳에서 Google을 찾지 않았습니다.
대신이 기사는 다음과 같이 표시됩니다.
Make sure inheritance models the is-a relationship.
My main guiding philosophy is that inheritance should be used only when a subclass is-a superclass. In the example above, an Apple likely is-a Fruit, so I would be inclined to use inheritance.
즉, IS_A 관계가있는 경우 상속을 먼저 사용하고 합성을 시도하지 마십시오. 그리고 선호도가 없습니다.using composition over inheritance- 각각은 자신의 역할에 도움이됩니다.
each is good for its own role.+1. 나는 이것이 "우리의 동기"에 달려 있음을 의미한다고 생각합니다. 이를 위해 우리는 우리 반 사이의 관계를 수립하고 있습니다. "ONLY"인 경우, 코드 재사용을 위해Favor composition over inheritance가 유효하고 "그 동기가"실제 관계 "를 모델링하는 것이라면, 실제로 클래스들 사이에 존재하기 때문에 상속과 구성 모두 자신의 역할을합니다. 순수 IS-A 관계가 "있음에도 불구하고"존재한다면 상속을 선택할 수있다. 상속은 강한 결합과 같은 구성보다 더 많은 문제가 있다는 사실, 그렇지 않으면 구성을 선택합니다. 내가 맞습니까? - a Learner
또한, 나는 그것을 추가하고 싶다.장식 패턴는 composition over inheritance를 사용하고 객체에 대한 책임을 동적으로 추가 할 수있는 예제입니다. Decorator 패턴의 예제는 "Inheritance Over Composition Composition"항목에서 Effective Java에 언급되어 있습니다. Java API에서 예제를 얻으려면; BufferedReader는 Reader (FileReader, PipedReader, FilterReader 등을 확장하는 대신)를 장식하므로 모든 종류의 Reader를 꾸밀 수 있습니다. 버퍼링 기능은 런타임에 이러한 판독기에 부착되며 Decorator 패턴입니다.
여기서 서브 클래 싱을 통한 확장은 비실용적입니다.
나는 좋은 지침이 될 것이라고 생각한다.
IS-A 관계가있을 때, 상속을 사용하십시오. 그렇지 않으면 구성.
그 이유는 객체 지향 디자인 (polymorphism)이라는 또 다른 개념과 관련이 있기 때문입니다. 다형성 (Polymorphism)은 다른 객체 대신에 객체를 사용할 수있는 많은 OOP 언어의 특징입니다. 단, 첫 번째 객체의 클래스는 두 번째 객체의 하위 클래스입니다.
설명하기 위해 동물의 유형을 취하는 함수가 있는지 상상해보십시오. 상속을 사용하면 하나의 함수 만 사용할 수 있습니다.
void feed( Animal a );
다형성 (Polymorphism)은 동물의 하위 클래스가 받아 들여질 것이라는 확신을줍니다. 그렇지 않으면 각 유형에 대해 하나의 함수를 작성해야합니다. 이 장점은 단점 (예 : 축소 된 캡슐화)을 능가한다고 생각합니다.
IS-A 관계가 없다면 다형성이 그리 효과적이지 않을 것이라고 생각합니다. 따라서 컴포지션을 사용하고 클래스간에 캡슐화 / 격리를 강화하는 것이 좋습니다.
If there is no IS-A relationship, I think polymorphism won't be very effective. It would thus be better to use composition and have enhanced encapsulation/isolation between classes.+1 - a Learner
관계가 영구적 일 때 상속을 사용하십시오. 자유로운 행동을하기 위해 확장 기능을 사용하지 마십시오. 이것이 IS-A 예제에서 언급 한 것입니다. 확장 클래스가 진정으로 부모의 확장 인 경우에만 확장하십시오. 그것이 잘리고 건조하지 않은 때가있을 것입니다, 그러나 일반적으로. 작문은 "올바른"수업에서 연장해야하는 경우에도 미래에도 유연성을 제공합니다.
이것은 오래되었지만 훌륭한 기사입니다.
http://www.javaworld.com/javaworld/jw-08-2003/jw-0801-toolbox.html
나는 안된다고. 과일 / 사과 시나리오에서는 상속을 사용하는 것이 좋습니다. 이 기사의 저자는 "위의 예에서 Apple은 과일 일 가능성이 높습니다. 따라서 상속을 사용하려고합니다."라고 확인했습니다.
하위 클래스가 분명히 수퍼 클래스이면 상속이 좋습니다. 실제로는 작곡을 사용하면 더 많은 상황을 해결할 수 있습니다.
<what-your-subclass-models>명확하게 IS-A<what-your-superclass-models>" - Joffrey