
상속
기존 정의되어 있는 클래스의 필드와 메소드를 물려받아 새로운 클래스를 생성하는 기법
- 중복코드 제거와 기능 확장 쉽게할 수 있음
- 클래스들의 계층적인 구조를 만들수도 있음
문제점
- 상속은 부모 클래스와 강하게 의존하고 부모 클래스의 캡슐화를 해치고 결합도가 높아진다.
- 부모 클래스의 구현을 변경하면, 많은 자식 클래스를 모두 변경 해줘야 하는 상황이 생길 수 있다.
- ex) 부모 class의 속성 a : 배열 -> List로 변경
- 생성자 내부에 this.a = 배열 -> List로 변경
- 자식 class에서 super 키워드로 부모의 생성자 호출 시 구조를 변경해야 함
- 불필요한 부모 클래스의 퍼블릭 메서드가 자식 클래스도 어쩔 수 없이 노출하게 된다.
- 공개된 부모 클래스의 퍼블릭 메서드가 자식 클래스의 내부 규칙과 맞지 않을 수 있다
- ex) Vector 상속받은 stack => Vector의 add 메서드로 데이터 삽입될 인덱스 지정 가능
- 스택은 후입 선출인데, 그것과 무관하게 동작함
조합
전체를 표현하는 클래스가 부분을 표현하는 객체를 포함해서 부분 객체의 코드를 재사용하는 방법
- 상속과 달리 부분 객체의 내부 구현이 공개되지 않음
- 메서드 호출하는 방식으로 퍼블릭 인터페이스에 의존해서 부분 객체의 내부 구현이 변경되어도 비교적 안전
- 부분 객체의 모든 퍼블릭 메서드를 공개하지 않아도 된다
조합 방법
조합하고 싶은 클래스의 인스턴스를 새로운 클래스의 private 필드로 참조, 이후 인스턴스의 메서드를 호출하는 방식으로 구현

- lotto의 numbers 속성이 List건 배열이건 영향x(캡슐화를 지킴)
- lotto의 getMatchCount 메서드의 내부 구현이 변경되든 안되든 영향이 없음
-> 부분 객체의 캡슐화를 지킴 + 부분 객체의 퍼블릭 인터페이스 의존(내부 구현의 변경 영향x)

- 부분 객체의 모든 공개 메서드를 노출하지 않아도 됨
- 스택에 필요했던 메서드인 push와 pop만 Vector의 public 메서드를 호출해서 구현
상속이냐 조합이냐
상속의 목적을 확실히 알고 사용해야 한다.
- 서브타이핑 : 다형적인 계층구조 구현(부모와 자식 행동 호환)
- 서브클래싱 : 다른 클래스의 코드 재사용(부모와 자식 행동이 호환x)
- 단순 코드 재사용을 위한 상속
- Vector와 Stack을 예시로 들 수 있음
- 단순 코드 재사용을 위해 상속하다 보면 서로 다르게 행동하는 객체들이 서로 강하게 결합되고 불필요한 행동 노출
상속 고려사항
아래 두 사항 모두 Yes일 때만 상속 사용 고려한다.
- Is-A 관계인가?
- 클라이언트 관점에서 두객체가 동일한 행동을 할 것이라 기대하는가?
정리
- 단순히 코드 재사용? 조합 고려(상속 x)
- 동일하게 행동하는 인스턴스를 그룹화?(상속 고려)