합성과 유연한 설계
상속 관계는 is-a 관계다.
합성 관계는 has-a 관계다.
상속을 제대로 활용하기 위해서는 부모 클래스의 내부 구현에 대해 상세하게 알아야 하기 때문에 자식 클래스와 부모 클래스 사이의 결합도가 높아질 수밖에 없다.
상속을 합성으로 변경하기
오퍼레이션을 오버라이딩한 인스턴스 메서드에서 내부의 특정 인스턴스에게 동일한 메서드 호출을 그대로 전달한다.
이를 포워딩이라 부르고 동일한 메서드를 호출하기 위해 추가된 메서드를 포워딩 메서드라고 부른다.
기존 클래스의 인터페이스를 그대로 외부에 제공하면서 구현에 대한 결합 없이 일부 작동 방식을 변경하고 싶은 경우에 사용할 수 있다.
import java.util.Collections; import java.util.Set; public class InstrumentdHashSet<E> implements Set<E> { private int addCount = 0; private Set<E> set; public InstrumentdHashSet(Set<E> set) { this.set = set; } @Override public boolean add(E e) { addCount++; return set.add(e); } @Override public boolean addAll(Collection<? extends E> c) { addCount += c.size(); return set.addAll(c); } }
추상 메서드와 훅 메서드
훅 메서드 : 메서드에 기본 구현을 제공함으로써 선택적 오버라이딩을 통해 중복 코드를 제거한다.
중복 코드의 덫에 걸리다
상속을 이용한 해결 방법은 모든 가능한 조합별로 자식 클래스를 하나씩 추가하는 것이다.
클래스 폭발 문제는 자식 클래스가 부모 클래스의 구현에 강하게 결합되도록 강요하는 상속의 근본적인 한계 때문에 발생하는 문제다.
합성 관계로 변경하기
우리는 오직 하나의 클래스만 추가하고 런타임에 필요한 정책들을 조합해서 원하는 기능을 얻을 수 있다.
객체 합성이 클래스 상속보다 더 좋은 방법이다.
구체적은 코드를 재사용하면서도 낮은 결합도를 유지할 수 있는 유일한 방법은 재사용에 적합한 추상화를 도입하는 것이다.
믹스인
객체를 생성할 때 코드 일부를 클래스 안에 섞어 넣어 재사용하는 기법.(추상 서브클래스)
슈퍼클래스는 서브클래스를 명시하지 않고도 정의될 수 있다. 슈퍼클래스로부터 상속될 클래스를 명시하는 메커니즘을 표현한다.
하나의 믹스인은 매우 다양한 클래스를 도출하면서 서로 다른 서브 클래스를 이용해 인스턴스화될 수 있다.
![[오브젝트] 11장 합성과 유연한 설계](/_next/image?url=https%3A%2F%2Fwww.notion.so%2Fimage%2Fattachment%253Ae47bc891-746c-4fa4-8237-814e4e1e22bb%253A%25E1%2584%258B%25E1%2585%25A9%25E1%2584%2587%25E1%2585%25B3%25E1%2584%258C%25E1%2585%25A6%25E1%2586%25A8%25E1%2584%2590%25E1%2585%25B3.jpeg%3Ftable%3Dblock%26id%3D25ea12d0-8f8e-803f-98a1-f7dedf32e50c%26cache%3Dv2&w=1920&q=75)