출처 : 오브젝트 (조영호 저)
객체지향은 클래스가 아닌 객체에 초점을 맞춰야 한다.
캡슐화를 통해 데이터와 기능을 객체 내부로 숨기는데, 객체를 자율적인 존재로 만들기 위해서다.
클래스 작성자는 클라이언트 프로그래머에게 필요한 부분만 공개하고 나머지는 꽁꽁 숨겨야 한다. 이를 구현은닉(implementation hiding)이라고 부른다. 객체 외부와 내부를 구분하면 클라이언트 프로그래머가 알아야 할 지식의 양이 줄어든다.
객체가 다른 객체와 상호작용할 수 있는 유일한 방법은 메시지를 전송하는 것 뿐이다.
컴파일 시점 의존성과 실행 시점의 의존성이 다르면 다를 수록 유연해지고 확장 가능해지나, 코드를 이해하기 어려워진다. 이런 양면성은 설계가 트레이드오프의 산물이라는 사실을 잘 보여준다.
다형성은 컴파일 시간 의존성과 실행시간 의존성이 다를 수 있다는 사실을 기반으로 한다. 다형성이란 동일한 메시지를 수신했을 때 객체 타입에 따라 다르게 응답할 수 있는 능력을 의미한다.
다형성은 메시지와 메서드를 실행 시점에 바인딩 한다. 이를 지연 바인딩(lazy binding) 또는 동적 바인딩(dynamic binding)이라고 부른다. 이에 반해 전통적인 함수 호출은 초기 바인딩(early binding) 또는 정적 바인딩(static binding)이라고 한다.
추상화를 사용하면 세부적인 내용을 무시한 채 상위 개념만으로도 도메인의 중요한 개념을 설명할 수 있게 한다. 또한 추상화를 이용하면 기존 구조를 수정하지 않고도 새로운 기능을 쉽게 추가하고 확장 할 수 있다. 추상화가 유연한 설계를 가능하게 하는 이유는 설계가 구체적인 상황에 결합되는 것을 방지하기 때문이다.
상속은 코드의 재사용이 가능하나 캡슐화를 위반하고, 설계를 유연하지 못하게 한다. 부모 클래스의 구현이 자식 클래스에게 노출되므로 자식과 부모가 강하게 결합된다. 상속은 부모와 자식의 관계를 컴파일 시점에 결정한다. 따라서 실행 시점에 객체의 종류를 변경하는 것이 불가능하다.
합성은 인터페이스를 통해 약하게 결합되고 실행시점에 객체타입이 결정되며, 인터페이스에 정의된 메시지를 통해서만 코드를 재사용한다. 인터페이스의 메시지를 통해서만 재사용이 가능하므로 구현을 효과적으로 캡슐화 할 수 있고, 메시지를 통해 느슨하게 결합된다.
따라서 코드 재사용을 위해서는 상속보다는 합성을 선호하는 것이 더 좋은 방법이다.