- 사람들은 도메인에 존재하는 개념들을 구조화하고 단순화하기 위해 다양한 추상화 기법을 사용한다.
- 분류와 인스턴스화
- 일반화와 특수화
- 집합과 분해
개념과 범주
- 객체를 분류하고 범주로 묶는 것은 객체들의 특정 집합에 공통의 개념을 적용하는 것을 의미한다.
- 객체들을 공통적인 특성을 기반으로 범주로 묶고 개념을 적용하는 것
- 범주라는 정신적인 렌즈를 통해 세상을 바라보는 것과 유사하다.
- 범주와 개념은 인간이 실세계를 바라보는 인식의 형태를 빚는다.
- 세상에 존재하는 객체에 개념을 적용하는 과정을 분류라고 한다.
- 분류는 객체를 특정한 개념을 나타내는 집합의 구성 요소로 포함시킨다.
- 객체지향의 세계에서 개념을 가리키는 표준 용어는 타입이다.
- 객체를 타입의 인스턴스라고 한다.
- 요약
- 분류는 객체와 타입 간의 관계를 나타낸 것
- 어떤 객체가 타입의 정의에 부합할 경우 그 객체는 해당 타입으로 분류되며 자동으로 타입의 인스턴스가 된다.
타입
- 타입을 객체의 분류 장치로서 적용할 수 있으려면 다음과 같은 세 가지 관점에서의 정의가 필요하다.
- 심볼: 타입을 가리키는 간략한 이름이나 명칭
- 내연: 타입의 완전한 정의
- 내연의 의미를 이용해 객체가 타입에 속하는지 여부 확인 가능
- 외연: 타입에 속하는 모든 객체들의 집합
외연과 집합
- 집합은 외연을 가리키는 또 다른 명칭
- 대부분의 객체지향 프로그래밍 언어들은 단일 분류만을 지원한다.
- 단일 분류: 한 객체가 한 시점에 하나의 타입에만 속하는 것
- 다중 분류: 한 객체가 한 시점에 여러 타입에 속할 경우
- 우리가 사용하는 대부분의 언어는 정적 분류만 허용.
- 즉, 객체의 타입을 변경할 수 없다.
- 동적 분류: 객체가 한 집합에서 다른 집합의 원소로 자신이 속하는 타입을 변경할 수 있는 경우
- 정적 분류: 객체가 자신의 타입을 변경할 수 없는 경우
클래스
- 객체지향 프로그래밍 언어를 이용해 타입을 구현하는 가장 보편적인 방법은 클래스를 이용하는 것
서브타입
- 일반화와 특수화는 계측 구조 안에 존재하는 타입 간의 관계를 의미
- 슈퍼타입: 어떤 타입이 다른 타이보다 일반적
- 서브타입: 어떤 타입이 다른 타입보다 특수
상속
- 프로그래밍 언어를 이용해 일반화와 특수화 관계를 구현하는 가장 일반적인 방법은 클래스 간의 상속을 사용하는 것.
- 그러나 프로그램 내의 두 클래스 간에 상속 관계가 존재할 때 이 관계를 반드시 일반화 관계라고 할 수 없다.
- 상속의 또 다른 용도는 코드 중복을 방지하고 공통 코드를 재사용하기 위한 언어적 메커니즘을 제공하는 것
- 가능한 모든 상속 관계가 서브타이핑의 대체 가능성을 준수하도록 주의 깊게 사용하는 것은 코드를 유연하게 만들고 재사용성을 높이는 한 가지 방법이다.
- 서브타이핑: 서브클래스가 슈퍼클래스를 대체할 수 있는 경우
- 서브클래싱: 서브클래스가 슈퍼클래스를 대체할 수 없는 경우
- 여러 클래스로 구성된 상속 계층에서 수신된 메시지를 이해하는 기본적인 방법은 클래스 간의 위임을 사용하는 것이다.
- 클래스가 없는 프로토타입 기반 언어에서도 동일하게 메시지를 수신한 객체가 자신이 메시지를 이해할 수 없을 경우 부모 객체에게 위임 → 프로토타입 체인
계층적인 복잡성
- 집합: 안정적인 형태의 부분으로서 전체를 구축하는 행위
- 분해: 전체를 부분으로 분할하는 행위
- 집합의 가치는 많은 수의 사물들의 형상을 하나의 단위로 다룸으로써 복잡성을 줄일 수 있다는 데 있다.
- 집합은 불필요한 세부사항을 추상화한다.
- 그러나 필요한 시점에는 전체를 분해함으로써 그 안에 포함된 부분들을 새로운 전체로 다룰 수 있다.
- 전체와 부분 간의 일관된 계층 구조는 재귀적인 설계를 가능하게 한다.
합성 관계
- 객체와 객체 사이의 전체-부분 관계를 구현하기 위해서는 합성 관계를 사용한다.
- 합성 관계는 부분을 전체 안에 캡슐화함으로써 인지 과부하를 방지한다.
- 연관 관계: 단순한 물리적 통로만 존재
패키지
- 상공에서 바라본 소프트웨어의 전체적인 구조를 표현하기 위해 관련된 클래스 집합을 하나의 논리적인 단위로 묶는 구성 요소를 패키지 또는 모듈이라고 한다.