이 질문에는 이미 답변이 있습니다.
상속에 대한 컴포지션 우선 순위 지정
매우 인기있는 문구입니다. 나는 몇몇 기사를 읽고 각 기사는 끝에 말한다
클래스 사이에 순수한 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