Skip to content

서브클래싱과 서브타이핑

Published: at 오전 07:07

Table of contents

Open Table of contents

Intro

상속이 사용되는 두 가지 용도

타입 계층 구현 부모 클래스에서는 일반화하고 자식 클래스는 부모 클래스를 특수화한다.

코드 재사용 간단한 선언만으로 부모 클래스의 코드를 재사용할 수 있다. 재사용을 위해 상속을 사용할 경우 부모 클래스와 자식 클래스가 강하게 결합되기 때문에 변경하기 어려운 코드를 얻게될 확률이 높다.

상속은 동일한 메시지에 대해 서로 다르게 행동할 수 있는 다형적인 객체를 구현하기 위해 객체의 행동을 기반으로 타입 계층을 구성하기 위해 사용해야 한다.

타입

개념 관점의 타입

타입의 구성요소

프로그래밍 언어 관점의 타입

프로그래밍 언어 관점에서 타입은 비트 묶음의 의미를 부여하기 위해 정의된 제약과 규칙을 가리킨다.

객체지향 패러다임 관점의 타입

타입을 두 가지 관점에서 정의할 수 있다.

객체지향에서 타입을 정의하는 것은 퍼블릭 인터페이스를 정의하는 것과 동일하다. 동일한 퍼블릭 인터페이스를 제공하는 객체들은 동일한 타입으로 분류된다.

타입 계층

타입 사이의 포함관계

슈퍼타입

서브타입

객체지향 프로그래밍과 타입 계층

퍼블릭 인터페이스 관점에서 슈퍼타입과 서브타입

슈퍼타입 서브타입이 정의한 퍼블릭 인터페이스를 일반화시켜 상대적으로 범용적이고 넓은 의미로 정의한 것이다. 서브타입 슈퍼타입이 정의한 퍼블릭 인터페이스를 특수화시켜 상대적으로 구체적이고 좁은 의미로 정의한 것이다.

서브타입의 인스턴스는 슈퍼타입의 인스턴스로 간주될 수 있다.

덕타이핑

One of TypeScript’s core principles is that type checking focuses on the shape that values have. This is sometimes called “duck typing” or “structural subtyping”. In TypeScript, interfaces fill the role of naming these types, and are a powerful way of defining contracts within your code as well as contracts with code outside of your project.

타입스크립트의 타입 체크는 값의 형태(shape)에 초점을 맞춘다. 이를 때로는 “덕 타이핑” 또는 “구조적 서브타이핑”이라고 한다. 타입스크립트에서 인터페이스는 이러한 타입을 명명하는 역할을 하며 코드 내부와 프로젝트 외부의 코드와의 계약을 정의하는 강력한 방법이다.

타입스트립트 - 인터페이스

interface LabeledValue {
  label: string;
}

function printLabel(labeledObj: LabeledValue) {
  console.log(labeledObj.label);
}

let myObj = { size: 10, label: "Size 10 Object" };
printLabel(myObj);

서브클래싱과 서브타이핑

어떤 타입이 다른 타입의 서브타입이 되기 위해서는 어떤 조건을 만족해야 할까?

서브타입의 퍼블릭 인터페이스가 슈퍼타입의 퍼블릭 인터페이스보다 더 특수하다는 것은 어떤 의미일까?

언제 상속을 사용해야 하는가?

타입 계층을 구현할 때

is-a 관계

어떤 타입 S가 다른 타입의 T의 일종이라면 “타입 S는 타입 T이다(S is-a T)“라고 말할 수 있다.

펭귄은 새다, 새는 날 수 있다. 하지만 펭귄은 날 수 없다. 어휘적인 정의가 아니라 기대되는 행동에 따라 타입 계층을 구성해야 한다.

행동 호환성

행동의 호환 여부를 판단하는 기준은 클라이언트의 관점 이라는 것이다.

합성을 사용해서 행동을 분리하고 인터페이스를 정의하면 클라이언트의 기대에 따라 인터페이스를 분리할 수 있다.

인터페이스를 클라이언트의 기대에 따라 분리함으로써 변경에 의해 영향을 제어하는 설계 원칙을 인터페이스 분리 원칙 이라고 부른다.

클라이언트의_기대에_따른_인터페이스_분리.png

서브클래싱과 서브타이핑

리스코프 치환 원칙

상속 관계로 연결한 두 클래스가 서브타이핑 관계를 만족하기 위해서는 다음의 조건을 만족시켜야 한다.

서브타입은 그것의 기반 타입에 대해 대체 가능해야 한다.

결론적으로 상속이 서브타이핑을 위해 사용될 경우에만 is-a 관계다. 서브클래싱을 구현하기 위해 상속을 사용했다면 is-a 관계라고 말할 수 없다.

리스코프 치환 원칙은 유연한 설계의 기반이다

DIP_LSP_OCP가_조합된_유연한_설계.png

계약에 의한 설계와 서브 타이핑

클라이언트와 서버 사이의 협력을 의무(obligation)와 이익(benefit)으로 구성된 계약의 관점에서 표현하는 것을 계약에 의한 설계 라고 부른다.

계약의 의한 설계 구성 요소