IT이야기

상속보다 구성을 선호

cyworld 2021. 4. 25. 12:39
반응형

상속보다 구성을 선호


이 질문에 이미 답변이 있습니다.

상속보다 구성을 선호

매우 인기있는 문구입니다. 나는 여러 기사를 읽었고 끝에 각 기사는

클래스간에 순수한 IS-A 관계가있을 때 상속을 사용합니다.

이 기사 의 예 :

여기 AppleFruit 사이 에는 명확한 IS-A 관계, 즉 Apple IS-A Fruit이 있지만 저자는 상속으로 구현할 때 함정을 보여주기 위해 Apple HAS-A Fruit (구성)로도 표시했습니다.

나는 여기서 진술의 의미가 무엇인지 다소 혼란스러워했습니다.

클래스간에 순수한 IS-A 관계가있을 때 상속을 사용합니다.

항상 상속 평균 이상 조성물을 사용합니까 시도 구성을 적용 할 경우에도 순수 IS-A 관계 및 휴가 상속이 단지 조성이 이해가되지 않습니다 이러한 경우에 대한이 ?


메서드를 재정의하고 다른 다형성 동작을 정의하는 대신 상속을 사용하여 수퍼 클래스의 코드를 재사용 할 때 상속 대신 합성을 사용해야한다는 표시가되는 경우가 많습니다.

java.util.Properties클래스는 상속을 잘못 사용하는 좋은 예입니다. 대신 사용하여 등록 정보를 저장하는 해시 테이블을, 그 연장 위해 그 방법을 재사용 및 위임을 사용하여 그 중 일부를 피하기 위해 다시 구현에서, 해시 테이블.


이것이 Object Oriented 디자인에서 가장 많이 논의 된 점 중 하나라고 생각합니다. 기사에서 제안했듯이 구성은 상속보다 항상 선호됩니다. 그렇다고 상속을 사용해서는 안된다는 의미는 아닙니다. 당신은 그것이 더 합리적이어야합니다 (논쟁의 여지가 있음).

컴포지션을 사용하면 많은 장점이 있으며 그중 두 가지는 다음과 같습니다.

  • 구현을 완전히 제어 할 수 있습니다. 즉, 노출하려는 메서드 만 노출 할 수 있습니다.
  • 수퍼 클래스의 모든 변경 사항은 클래스에서만 수정하여 보호 할 수 있습니다. 클래스를 사용하는 클라이언트 클래스는 수정할 필요가 없습니다.
  • 수퍼 클래스를로드 할시기를 제어 할 수 있습니다 (지연로드).

좋은 지침은 다음과 같습니다.

IS-A 관계가있는 경우 상속을 사용하십시오. 그렇지 않으면 구성을 사용하십시오.

그 이유는 객체 지향 디자인의 또 다른 개념 인 다형성과 관련이 있습니다. 다형성은 첫 번째 클래스가 두 번째 클래스의 하위 클래스 인 경우 다른 개체 대신 개체를 사용할 수있는 많은 OOP 언어의 기능입니다.

예를 들어, 동물의 한 유형을 취하는 함수가 있다고 상상해보십시오. 상속을 사용하는 경우 하나의 기능 만 있습니다.

void feed( Animal a );

다형성은 우리가 넣은 동물의 모든 하위 클래스가 허용된다는 것을 보장합니다. 그렇지 않으면 각 유형에 대해 하나의 함수를 작성해야합니다. 나는 이것의 장점이 단점보다 크다고 생각합니다 (예 : 캡슐화 감소).

IS-A 관계가 없다면 다형성이 그다지 효과적이지 않을 것이라고 생각합니다. 따라서 컴포지션을 사용하고 클래스 간의 캡슐화 / 격리를 강화하는 것이 더 좋습니다.


기사에는 다음과 같은 문구가 없습니다.

use inheritance when there is pure IS-A relationship between classes

또한 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-각각은 자신의 역할에 좋습니다.


또한 Decorator 패턴 은 상속보다 합성을 사용하고 객체에 대한 책임을 동적으로 추가 할 수있는 예제 라는 것을 추가하고 싶습니다 . 데코레이터 패턴의 예는 "상속보다 구성 선호"항목의 Effective Java에 언급되어 있습니다. Java API에서 예제를 가져옵니다. BufferedReader는 (FileReader, PipedReader, FilterReader 등을 확장하는 대신) Reader를 장식하므로 모든 종류의 Reader를 장식 할 수있는 기능이 있습니다. 버퍼링 기능은 데코레이터 패턴 인 런타임에 이러한 판독기에 연결됩니다.

여기서 서브 클래 싱에 의한 확장은 비실용적입니다.


관계가 영구적 인 경우 상속을 사용합니다. 자유로운 행동을 얻기 위해 확장 기능을 사용하지 마십시오. 이것이 그들이 IS-A 예제에서 언급 한 것입니다. 확장 클래스가 실제로 부모의 확장 인 경우에만 확장하십시오. 일반적으로 잘리지 않고 건조하지 않은 경우가 있습니다. 컴포지션은 "올바른"클래스에서 확장해야하는 경우에도 향후 유연성을 제공합니다.

이것은 오래되었지만 확장에 대한 훌륭한 기사입니다.

http://www.javaworld.com/javaworld/jw-08-2003/jw-0801-toolbox.html


나는 아니오라고 말할 것입니다. 과일 / 사과 시나리오에서는 상속을 사용하는 것이 좋습니다. 이 기사의 저자는 "위의 예에서 Apple은 과일 일 가능성이 높으므로 상속을 사용하는 경향이 있습니다."라고 확인합니다.

당신의 서브 클래스가 분명히 슈퍼 클래스라면 상속은 괜찮습니다. 그러나 실제로는 컴포지션을 사용하여 더 잘 해결되는 상황을 더 많이 찾을 수 있습니다.

참조 URL : https://stackoverflow.com/questions/11343840/favor-composition-over-inheritance

반응형