[JAVA] 상속과 조합 (Inheritance vs Composition)

이지우·2021년 1월 18일
1

JAVA

목록 보기
2/2

상속은 많이 들어보고 또 사용해봤는데, 조합은 뭔지 처음 들어봤다.

둘 사이에는 어떤 차이가 있고, 어떤 장단점이 있는지, 개발자로서 어떤것을 채택하는것이 바람직한지 알아보자.

상속을 사용하는 이유

  1. 하위 클래스는 공통적인 부분을 가진 상위 클래스를 활용하여 본인 고유의 상태와 행동을 정의하기 위해 사용한다.
  2. 코드의 확장성과 재사용성이 쉬워지고, 중복된 부분을 상위 클래스로 뭉뚱그려 뺐으므로 코드가 간결해진다.
  3. 결과적으로 유지보수가 쉬워지고, 개발시간이 단축된다.

결론부터 말하자면,

  • 상속보다는 조합을 사용하자.

    우리가 흔히 사용하는 상속은 코드를 재사용할 수 있는 강력한 수단임은 틀림없다.
    하지만 상위 클래스의 구현이 바뀌면 이 클래스를 상속받은 하위 클래스에도 영향을 미치게 되므로 캡슐화를 깨트리게 된다.

    상속은 상위 클래스에 결함이 있을 때, 그 결함까지 그대로 상속받게 된다.
    극단적으로 예시를 잘 들어놓은 코드가 있길래 뜯어보았다. 만약 전화기 클래스에서 usePhone()이 손으로 사용하는것에서 발로 사용하는것으로 바뀌었을 때, 이를 상속받는 스마트폰 클래스도 발로 사용해야 하는 것이다.
    하지만 조합(컴포지션)은 이런 결함을 숨기는 새로운 API를 설계할 수 있다.
    [그림출처] https://smjeon.dev/etc/composite-extends/

  • 그러나 조합은 상속을 전혀 사용하지 않는것이 아니다.

    디자인패턴에서,'Favor Object Composition over Class Inheritance' 라고 정의된 원칙이 있다. '구현 상속보다는 객체조합을 선호하라' 는 말로 해석된다.
    Erich Gamma의 인터뷰에서 이 원칙은 최종적으로 '구현 상속보다는 인터페이스 상속을 사용한 객체 조합을 선호하라' 는 말로 해석된다.
  • 상속은 기본적으로 상위-하위 클래스가 순수한 is-a 관계가 성립되어야 한다.

    • is-a 관계란

      위 그림에서 Student는 상위클래스인 Person을 상속받았다고 말한다.
      화살표 방향을 쉽게 이해하기 위해 Student is a Person 라는 문장으로 만들었을 때 옳은 문장이 되어야한다..는 방법이 있다. 즉 하위클래스 is a 상위클래스라는 말이다. (Person is a Student는 맞지 않는 말!)

      그래서 사실 스택도 상속의 is-a관계를 위반한 예시이다.
      Stack is a Vector이라는 문장이 좀 생소한데 이에 관한 자세한 정보가 나와있지 않아서 Stack is a Vector가 구체적으로 어떤것때문에 틀린 문장인지 모르겠다.

      is-a관계가 아니라면 클래스A를 클래스B의 private 인스턴스로 두면된다. 이를 조합(Composition)이라고 한다.

인터페이스 상속을 사용한 객체 조합 ??

인터페이스 상속을 사용한 객체조합이 무슨 말인지 간단한 예제를 통해 알아보자.

위 코드에서 Engine, Automobile, Car 클래스가 정의되어 있다.

  • Car 클래스는 Automobile을 상속받았다 (Car is a Automobile).
  • Car 클래스는 Engine클래스를 member로 가지고 있다 (Car has a(n) Engine).
    (즉 이런 관계로 보면 되겠다)

아래는 자바 Listener를 이용한 예시이다.

Button에 포함된 인터페이스로 ActionListener를 가졌고, ActionListener을 상속받은 객체인 SomeActionListener사이의 관계이다. 추가적으로, 조합 대상이 되는 SomeActionListener은 큰 클래스를 상속받기보다는 ActionListener같은 작은 인터페이스를 상속받는게 좋다.

[참고] https://happy-playboy.tistory.com/entry/Item-18-%EC%83%81%EC%86%8D%EB%B3%B4%EB%8B%A4%EB%8A%94-%EC%BB%B4%ED%8F%AC%EC%A7%80%EC%85%98%EC%9D%84-%EC%82%AC%EC%9A%A9%ED%95%98%EB%9D%BC

profile
개발 관찰일지

0개의 댓글