상속 vs 구성
상속과 유사하지만 상속과는 미묘하게 다른 구성(composition)이라는 기법이 있음
구성은 클래스가 다른 클래스의 인스턴스를 클래스의 필드로 가지는 디자인 기법 반면에 상속은 한객체가 클래스를 상속받아서 부모 객체의 속성과 동작을 휙득할 수 있는 기법
상속 및 구성은 객체지향 개발자가 사용하는 두가지의 중요한 프로그래밍 기술
상속은 한 클래스를 다른 클래스에서 파생시키는 반면 구성은 하나의 클래스를 다른 클래스의 합으로 정의
상속을 통해 생성된 클래스와 객체는 밀접하게 결합이 됨, 상속관계에서는 부모 클래스를 변경하면 코드가 손상될 위험이 있음 - 결합도가 높다
구성을 통해 생성된 클래스와 객체는 느슨하게 결합되어 코드를 손상시키지 않고 구성요소를 더 쉽게 변경할 수 있음 - 결합도가 낮다
느슨하게 결합된 코드가 더 많은 유연성을 제공하기 떄문에 많은 개발자들은 구성이 상속보다 더 나은 기술이라고 생각하기도 함 즉 결합도가 낮은게 더 좋다 생각함
상속
is - a 관계
상속에서는 하나의 클래스만 상속할 수 있으므로 하나의 클래스에서만 코드를 재사용
final로 선언된 클래스의 코드를 재사용 할 수 없음
구성
구성은 has - a 관계
여러 클래스의 코드를 재사용할 수 있음
final로 선언된 클래스의 코드도 사용할 수 있음
is - a 관계
a는 b의 일종이다 라고 말하는 것과 같음
예를 들어 사과는 과일의 일종이고, 자동차는 차량의 일종 is - a 관계가 있으면 상속을 사용 상속은 단방향
객체지향 프로그래밍에서 자식 크랠스와 부모 클래스 사이에 is - a 관계가 있을 때 사용
따라서 상속의 계층 구조를 올바르게 설계하였는지를 알려면 is - a 관계가 성립하는지를 생각하면 됨
상속 사용을 고려할 떄는 항상 자식 클래스가 실제로 부모 클래스의 특수한 버전인지 자문하는 것이 좋음 이 경우 강아지는 동물의 특수한 버전이므로 상속 관계가 맞음
흔히 자바 입문자의 경우 의욕에 넘쳐서 모든것을 상속으로 해결할려고 함
하지만 상속을 사용하는 경우, 부모 클래스와 자식 클래스 사이에는 강한 연관관계 가 생김
이 경우 부모 클래스가 변경되면 자식 클래스들도 모두 영향을 받음
물론 is - a 관계가 있는 클래스인 경우에는 상속을 사용하는 것이 장점이 많고 자연스로운 방법
하지만 is - a 관계가 아닌데도 무분별하게 상속을 사용하면 단점이 더 많음
has - a 관계
만약 '~은 ~을 가지고 있다' 와 같은 has - a(포함) 관계가 성립되면 이 관계는 상속으로 모델링을 하면 안됨, 이 경우에는 구성을 사용
자동차는 엔진을 가지고 있다.
도서관은 책을 가지고 있다 (Library has a book)
집은 욕실을 가지고 있다
객체 지향 프로그래밍에서 has - a 관계는 구성(composition) 또는 집합 (aggregation)을 의미
구성에서는 하나의 객체가 다른 객체의 부품이 됨
집합관계에서는 하느이 객체가 다른 객체를 소유하게 됨
has - a 관계가 성립되는 경우에는 상속을 이용하는 것이 아니라 하나의 클래스 안에 다른 클래스의 객체를 포함시키면 됨
is - a 관계 못지않게 has - a 관계를 이용하는 것도 중요
package chapter20230825;
class Vehicle{}
class Engine {}
class Brake {}
public class Car extends Vehicle{
private Engine e;
private Brake b;
public Car() {
this.e = new Engine();
this.b = new Brake();
}
}
위의 코드는 아주 간단하지만 is - a 관계와 has - a 관계가 동시에 들어가 있음
vehicle 클래스와 Car 클래스의 관계는 is - a 관계
하지만 Car 클래스와 Engine 클래스의 관계는 has - a 관계