조영호님의 책 오브젝트를 보며 정리한 내용입니다.
문제가 될 시 해당글 삭제하겠습니다.
상속의 2가지 용도
- 타입 계층 구현 : 부모 클래스는 일반적인 개념을 구현하고, 자식 클래스는 특수한 개념을 구현한다.
- 코드 재사용 : 상속만으로 자식 클래스는 부모 클래스의 코드를 재사용 할 수 있다. 하지만 부모 클래스와 자식 클래스가 강하게
결합된다는 단점 때문에, 객체 지향에서 권장되는 방법은 아니다.
→ 상속을 사용하는 일차적인 목표는 코드 재사용이 아닌 타입 계층을 구현하는 것이다.
→ 이를 위해서 객체의 행동을 기반으로 타입 계층을 구성해야 한다.
타입
- 개념 관점의 타입 → 공통의 특징을 공유
- 타입 : 우리가 인식하는 객체들에 적용하는 개념이나 아이디어를 가리켜 타입이라고 부른다.
- 심볼(symbol) : 타입에 이름을 붙인 것. ex) 프로그래밍 언어
- 내연(intension) : 타입의 정의 ex) 컴퓨터에게 지정된 명령을 하기위해 사용하는 언어
- 외연(extension) : 타입의 속하는 객체들의 집합 ex) 루비, 자바, 자바스크립트 등..
- 인스턴스 : 어떤 대상이 타입으로 분류될 때, 그 대상을 타입의 인스턴스라고 부른다.
- 타입 : 우리가 인식하는 객체들에 적용하는 개념이나 아이디어를 가리켜 타입이라고 부른다.
- 프로그래밍 언어 관점의 타입 → 동일한 오퍼레이션을 적용할 수 있는 인스턴스들의 집합
- 프로그래밍 언어 관점에서 타입은 연속적인 비트에 의미와 제약을 부여하기 위해서 사용된다.
- 타입에 수행될 수 있는 유효한 오퍼레이션(연산) 집합을 정의한다.
- 타입에 수행되는 오퍼레이션에 대해 미리 약속된 문맥을 제공한다.
- 객체지향 패러다임 관점의 타입
- 객체 지향 관점에서 오퍼레이션(연산)은 객체가 수신할 수 있는 메시지를 의미한다.
- 퍼블릭 인터페이스 : 객체가 수신할 수 있는 메시지의 집합!
- 객체지향 관점에서는 객체의 퍼블릭 인터페이스가 객체의 타입을 결정한다!!
→ 동일한 퍼블릭 인터페이스를 제공하는 객체들은 동일한 타입으로 분류된다. - 결론적으로 객체에게 중요한 것은 속성이 아닌 행동이라는 것이다!!
타입 계층
- 객체지향 프로그래밍과 타입 계층
- 슈퍼타입 : 서브타입이 정의한 퍼블릭 인터페이스를 일반화시켜 상대적으로 범용적이고 넓은 의미로 정의한 것이다!
- 서브타입 : 슈퍼타입이 정의한 퍼블릭 인터페이스를 특수화시켜 상대적으로 구체적이고 좁의 의미로 정의한 것이다.
→ 서브타입의 인스턴스는 슈퍼타입의 인스턴스로 간주될 수 있다.
서브클래싱과 서브타이핑
- is-a 관계
- 객체지향에서는 두 클래스가 is-a 관계를 모델링 할 경우에만 상속을 사용해야 한다.
-> 행동 호환성이 선행되어야 한다. - 타입 계층의 의미는 행동이라는 문맥에 따라서 달라질 수 있다. ex) 새는 날수 있지만, 펭귄은 날 수 없다..
- is-a 관계를 너무 단편적으로 받아들이는 것이 아닌, 행동 호환성이 더 중요하다.
- 객체지향에서는 두 클래스가 is-a 관계를 모델링 할 경우에만 상속을 사용해야 한다.
- 행동 호환성
- 행동 호환성에 연관이 없다면 is-a 관계를 맺어서는 안된다!
- 행동의 호환 여부를 판단하는 기준은 클리이언트의 관점이다.
- 클라이언트의 기대에 따라 계층 분리하기
- 인터페이스 분리 원칙(Interface Segregation Principle, ISP) : 인터페이스를 클라이언트의 기대에 따라 분리함으로써 변경에 의해 영향을 제어하는 설계 원칙
- 클라이언트의 기대 : 현실 세계에서 클라이언트가 납득할 수 있는 상황? ex) 새는 날수 있지만, 펭귄은 날 수 없다..
- 서브클래싱과 서브타이핑
- 서브클래싱 : 다른 클래스의 코드를 재사용할 목적으로 상속을 사용하는 경우 → 사용하지 말아야 할 방식
- 서브타이핑 : 타입 계층을 구성하기 위해 상속을 사용하는 경우
- 서브타이핑 관계가 유지되기 위해서는 서브타입이 슈퍼타입이 하는 모든 행동을 동일하게 할 수 있어야 한다. (행동 호환성) → 행동 호환성을 유지함으로 부모 클래스를 대체할 수 있도록 구현된 상속 관계만을 서브 타이핑이라 불러야만 한다!
- 자식 클래스와 부모 클래스 사이의 행동 호환성은 부모 클래스에 대한 자식 클래스의 대체 가능성을 포함한다.
리스코프 치환 원칙(Liskov Substitution Principle, LSP)
- 리스코프 치환 원칙 : 서브타입은 그것의 기반 타입에 대해서 대체 가능해야 한다.
→ 클라이언트가 차이점을 인식하지 못한 채 기반 클래스의 인터페이스를 통해 서브클래스를 사용할 수 있어야 한다.
ex) 직사각형을 상속하는 정사각형이 있다고 생각했을 때, 구현을 재사용할 수는 있지만, 높이와 너비를 구하는 과정에서 아예 다른 성격의 로직을 구현할 수 있다.
이때, 두 클래스는 리스코프 치환 원칙을 위반하기 때문에, 서브타이핑 관계처럼 보이더라도 서브클래싱 관계이다! - 리스코프 치환 원칙은 유연한 설계의 기반이다!
'아키텍처 > OOP' 카테고리의 다른 글
[오브젝트] Chapter12 다형성 (0) | 2022.11.17 |
---|---|
[오브젝트] Chapter10, 11 상속과 코드 재사용 / 합성과 유연한 설계 (0) | 2022.11.09 |
[오브젝트] Chapter9 유연한 설계 (0) | 2022.11.04 |
[오브젝트] Chapter8 의존성 관리하기 (2) | 2022.11.04 |
[오브젝트] Chapter7 객체 분해 (0) | 2022.11.03 |