JAVA/Architecture

상속과 합성 Inheritance And Composition

호두밥 2021. 12. 10. 01:40

상속 Inheritance

상속이란 부모 클래스의 기능을 자식 클래스에서 재사용하는 것을 말합니다. 코드의 중복을 줄이고, 재사용성을 높이기 위해 자바에서 사용하는 기능입니다. 

부모 클래스인 고양이의 "먹다"라는 기능(메소드)를 자식 클래스인 스핑크스에서 사용할 수 있습니다. 

 

상속의 문제점

불필요한 기능 상속 

자식 클래스에는 적합하지 않은 메소드가 상속되는 문제입니다. 예를 들어서 위의 그림에서 고양이 클래스에 "빗질하다"라는 메소드가 있다고 가정해봅니다. 그러면 자식 클래스인 "스핑크스"에서도 "빗질하다"라는 메소드를 사용할 수 있습니다. 하지만 털이 없는 스핑크스에게 "빗질하다"는 적합하지 않은 메소드입니다.  

 

부모 클래스의 기능 변경에 자식 클래스가 영향을 받음

부모 클래스의 기능을 자식 클래스에서 사용하고 있는 경우, 부모 클래스의 기능이 변경된다면, 그 기능을 사용하고 있는 자식 클래스의 기능에도 영향을 미치게 됩니다. 

자식 클래스에서는 부모 클래스의 기능이 변경되었는지를 확인할 수 없기 때문에 문제가 발생할 수 있습니다.

예를 들어서 오른쪽 그림과 같이 고양이 클래스의 "먹다"라는 기능이 "츄르"를 먹는 것으로 정의되어 있습니다. 이 기능을 가지고 고양이 클래스를 상속받은 코리안숏헤어 클래스에서 "놀다"라는 메소드를 만들었습니다.

만약 고양이 클래스의 "먹다"라는 기능이 "참치" 등으로 바뀌게 된다면, 코리안숏헤어 클래스에서 정의한 "놀다" 메소드의 의미에 영향을 미치게 됩니다. 

 

 

부모 클래스와 자식 클래스 동시 수정

부모 클래스의 메소드를 자식 클래스에서 오버라이딩(재정의)한 경우에 생길 수 있는 문제입니다.

예를 들어, 부모 클래스의 매개변수나 리턴값이 변경된 경우 오버라이딩한 자식 클래스에도 변경사항을 반영해주어야 합니다.   

오른쪽 그림에서 고양이 클래스의 "놀다" 메소드가 놀다(장난감)으로 변경되었다고 가정해봅니다. 그렇다면 놀다() 메소드를 오버라이드한 코리안숏헤어 클래스의 놀다() 메소드에도 매개변수 장난감를 추가해주어야 합니다.  

 

 

합성 Composition

합성이란 기능을 가진 객체 여러개를 묶어서 조합한 것을 말합니다. 상속에 의해 코드를 재사용하는 것 대신, 객체의 기능(퍼블릭 인터페이스)을 호출하는 방식을 통해 코드를 재사용하는 것입니다.

예를 들어서 아래와 같은 고양이 객체가 있습니다. 고양이 객체는 "놀이"라는 인터페이스 객체를 포함하고 있습니다. 어떻게 놀지를 내부에서 직접 메소드로 생성하지 않고, 외부에서 놀이 객체를 입력받아 선언하는 것입니다.  

고양이 꾼이 = new 고양이( new 놀이());
고양이 꾼이 = new 고양이( new 캣타워놀이());

고양이 클래스의 자식 클래스 "코리안숏헤어" 에서는 별도의 놀이는 메소드를 구현하거나, 오버라이드 하지 않아도 놀이 객체를 입력받는 방식으로 놀이 기능을 정의할 수 있습니다. 

코리안숏헤어 꾼이 = new 고양이( new 낚싯대놀이());

만약 "캣휠"이라는 놀이 기능이 추가되었다고 하면, 놀이 클래스 상속받은 클래스만 하나 더 생성해주면 됩니다. 고양이와 고양이를 상속받은 코리안숏헤어 클래스의 코드는 수정하지 않아도 됩니다.

 

상속과 합성의 차이

앞서 살펴본 것처럼 상속과 합성은 코드를 재사용 기법입니다. 

상속이 부모 클래스와 자식 클래스를 연결해서 코드를 재사용한다면, 합성은 부분 객체를 포함하여, 부분 객체의 기능을 재사용합니다. 그래서 상속은 is-a 관계, 합성은 has-a 관계라고 부릅니다. 

* 클래스 상속(구현상속)을 사용하는 것은 결합도를 증가시켜 코드 수정을 어렵게 합니다. 때문에 인터페이스 상속을 사용해 코드를 재사용하는 방향으로 설계해야 합니다.

구분 상속 Inheritance 합성 Composition
의존성 해결 시점 컴파일 런타임
결합도 높음 
부모 클래스의 기능 변경에 의해 자식 클래스가 영향을 많이 받음
낮음

 

믹스인 MixIn

객체를 생성할 때 코드 일부를 클래스 안에 섞어 넣어 재사용하는 기법입니다. 

참조 

조영호, 오브젝트, 위키북스, 2019

https://ko.wikipedia.org/wiki/%EB%AF%B9%EC%8A%A4%EC%9D%B8