본문 바로가기
언어 & 라이브러리/자바

[자바] 상속보다 합성을 사용해야 하는 이유

by illlilillil 2022. 9. 13.

상속이란?

상속은 상위 클래스에 로직을 구현하고 하위 클래스에스 코드를 재사용하는 방법이다. IS-A 관계로 불린다.

 

상속으로 얻는 장점?

외부의 접근으로 인한 다형성을 보장하고 공통된 로직을 사용할 수 있다. 하위 클래스에 따라 구현 로직만 변경해주면 된다는 장점이 있다.

그러나 Java 8의 인터페이스 Default 메소드 기능으로 이러한 상속의 장점도 불필요하게 되었다.

 

잘못된 상속으로 인한 오류들

1. 불필요한 인터페이스 상속 문제

하위 클래스에 부적합한 부모 클래스의 메소드를 물려받기에 자식 클래스의 캡슐화가 깨지는 문제가 발생한다.

대표적으로 자바의 Stack과 Vector 클래스가 있다. stack 클래스는 vertor를 상속받는 설계로 의도치 않는 동작이 실행되어 캡슐화를 깨뜨린다.

 

2. 메소드 오버라이딩 오작용 문제

하위 클래스가 상위 클래스의 메서드를 오버라이딩할때 호출 방법에 영향을 받는 문제가 있다. HashSet을 상속받는 InstrumentedHashSet의 오버라이딩 메서드가 HashSet의 메서드와 강하게 결합되어 있어 의도와는 다른 코드를 뱉는 문제이다.

 

3. 상위 클래스와 자식 클래스의 동시 수정 문제

두 클래스의 개념적인 결합으로 인해 부모 클래스를 변경할때 자식 클래스도 함께 변경해야 하는 문제가 있다.

 

잘못된 상속의 결과

캡슐화를 위반할 수 있다.

설계가 유연하지 않다.

 

-> 합성을 사용하자

합성이란?

합성은 런타임시 동적으로 이뤄지는 has-a 관계를 말한다. 합성은 코드를 재사용할때 유용하다. 합성으로 구현하면 상위 클래스에 의존없이 캡슐화를 조절할 수 있다. 

아래는 오브젝트 책에 있는 통신비 세율 계산 클래스이다. 상속에 의한 폭발적인 클래스 증가도 되지 않고 전략에 따라 구현 전략을 변경할 수 있다.

 

합성의 단점?

객체 관계가 수평적인 관계가 된다. 복잡한 시스템 구현에서 여러 합성이 구현된다면 가독성이 떨어져 구현에 어려움을 겪을 것이다. 목적에 맞게 패키지를 분리하고, 용도가 명확하게 드러나도록 잘 설계해야 한다.

 

결론

코드 재사용을 위해선 상속보단 합성을 이용하자.

상속을 사용할땐 명확한 IS-A 관계인지 확인하자.

댓글