서브 클래싱과 서브 타이핑
상속
객체지향 프로그래밍 언어에서 타입을 구현하는 일반적인 방법은 클래스를 이용하는 것이다. 그리고 타입 계층을 구현하는 일반적
인 방법
은 상속을 이용하는것이다. 상속을 이용해 타입 계층을 구현한다는 것은 부모 클래스가 슈퍼타입의 역할을, 자식 클래스가 서브타
입의 역할을 수행하도록 클래스 사이의 관계를 정의하는 것을 의미.
상속의 용도
- 타입계층을 구현하는 것 : 부모클래스는 자식클래스의 일반화(generalization), 자식클래스는 부모클래스의 특수화(specialization)
- 코드 재사용 : 점진적으로 어플리케이션을 확장. 부모 자식이 강하게 결합
상속 사용
is - a 관계
어떤 타입 S가 다른 타입 T의 일종이라면 당연히 “타입 S는 타입 T다( S is-a T )” 라고 말할 수 있어야 한다.
새와 펭귄을 예로 들면 is - a 관계가 쉽게 배신할 수 있다는 사실을 알 수 있다.
- 펭귄은 새다.
- 새는 날 수 있다.
즉 is-a 관계는 실제 세계의 개념적인 요소가 아닌 기대되는 행동에 따라 타입 계층을 구성해야 한다는 사실을 보여준다.
- 행동 호환성
타입의 이름 사이에 개념적으로 어떤 연광선이 있다고 하더라도 행동에 연관성이 없다면 is - a 관계를 사용하지 말아야 한다.
결론적으로 두 타입 사이에 행동이 호환될 경우에만 타입 계층으로 묶어야 한다는 것이다.
즉, 클라이언트 관점에서 두타입 모두 동일하게 행동할 것이라고 기대한다면 두 타입을 타입 계층을 묶을 수 있지만 동일하지 않다고 기대
한다면 묶어서는 안된다.

- 상속 계층 분리함으로 펭귄을 더이상 fly 메시지 수신하지 않음

- 행동기반으로 인터페이스를 구현하여 Bird 와 Penguin 은 자신이 수행할 인터페이스만 구현한다.
이러한 설계원칙은 인터페이스 분리 원칙(ISP) 라고 부른다.
서브 클래싱과 서브 타이핑
- 서브클래싱 : 다른 클래스의 코드를 재사용할 목적으로 상속을 사용하는 경우를 가리킴.
-자식 클래스와 부모 클래스의 행동이 호환되지 않기 때문에 자식 클래스의 인스턴스가 부모 클래스의 인스턴스를 대체할 수 없음.
-서브 클래싱을 구현 상속(implementation inheritane) 또는 클래스 상속(class inheritance)이라고 부르기도 한다.
- 서브타이핑 : 타입 계층을 구성하기 위해 상속을 사용하는 경우를 가리킴.
- 타입 계층을 구성하기 위해 상속을 사용하는 경우
- 자식 클래스와 부모 클래스의 행동이 호환되기 때문에 자식 클래스의 인스턴스가 부모 클래스의 인스턴스를 대체할 수 있음
- 부모 클래스는 자식 클래스의 슈퍼타입이 되고 자식 클래스는 부모 클래스의 서브타입이 됨
- 인터페이스 상속(interface inheritance) 이라고 부르기도 함
서브타이핑
-
슈퍼타입과 서브타입 사이에서 가장 중요한 것은 퍼블릭 인터페이스이다.
-
서브타입의 퍼블릭 인터페이스가 슈퍼타입에서 정의된 퍼블릭 인터페이스와 동일하거나 더 많은 오퍼레이션을 포함해야 한다.
-
그에 반해 서브 클래싱은 내부 구현 자체를 상속받는것에 초점을 모은다.
-
서브타이핑 관계를 유지하기 위해 서브타입이 슈퍼타입이 하는 모든 행동을 동일하게 할 수 있어야 한다. 즉 행동호환성 을 만족시켜햐 한다.
-
이 행동호환성은 부모클래스에 대한 자식 클래스의 대체 가능성으로 이어진다.
리스코프 치환 원칙(LSP)
-
서브타입은 그것의 기반 타입에 대해 대체 가능해야 함을 의미
-
즉 자식 클래스가 부모 클래스와 행동 호환성을 유지함으로써 부모 클래스를 대체할 수 있도록 구현된 상속 관계만을 서브타이핑이라고 부른다.
참고 자료