목표
TypeScript로 짜여진 예시를 통해 객체지향의 핵심 개념 (캡슐화, 추상화, 상속, 다형성)을 모두 이해한다.
Step1. 커피머신 클래스 만들기
커피머신에 필요한 변수와 함수에는 어떤 것들이 있을까?
// 커피를 타입으로 선언
type Coffee = {
shots: number;
hasMilk: boolean;
};
class CoffeeMachine {
// 변수 선언
static BEANS_GRAM_PER_SHOT: number = 7; // 클래스 레벨
coffeeBeans: number = 0; // 인스턴스 레벨
// 커피머신 객체를 만들 때 호출되는 생성자
constructor(coffeeBeans: number) {
this.coffeeBeans = coffeeBeans;
}
// 함수 정의
// 커피 만들기 함수. 샷을 인자로 받아서 커피를 리턴한다.
makeCoffee(shots: number): Coffee {
if (this.coffeeBeans < shots * CoffeeMachine.BEANS_GRAM_PER_SHOT) {
throw new Error('Not enough coffee beans!');
}
this.coffeeBeans -= shots * CoffeeMachine.BEANS_GRAM_PER_SHOT;
return {
shots,
hasMilk: false,
};
}
}
const machine = new CoffeeMachine(32); // 커피머신 객체 생성
console.log(machine); // CoffeeMachine { coffeeBeans: 32 }
Step 2. 클래스 변수 캡슐화 하기 (Encapsulation)
클래스 외부에서 변수를 임의로 수정할 수 없도록 캡슐화 한다.
수정 필요한 변수는 함수를 통해서만 접근 가능하다.
- public: 외부에서 접근 가능
- private: 외부에서 접근 불가
- protected: 상속받은 자식에서만 접근 가능
private static BEANS_GRAM_PER_SHOT: number = 7;
private coffeeBeans: number = 0;
// coffeeBeans 변수를 수정하는 함수
fillCoffeeBeans(beans: number) {
if (beans < 0) {
throw new Error('value for beans should be greater than 0');
}
this.coffeeBeans += beans;
}
Step 3. 인터페이스로 추상화 하기 (Abstraction)
인터페이스는 마치 커피머신의 설명서 같은 것이다.
인터페이스를 통해 클래스에 어떠한 함수가 있는지 파악할 수 있다.
하나의 클래스는 여러 인터페이스를 구현할 수 있다.
※ 인터페이스는 앞에 I를 붙여서 표현하는 방법이 있다.
※ A implements B = A는 B를 구현한다.
interface ICoffeeMachine {
makeCoffee(shots: number): Coffee;
}
class CoffeeMachine implements ICoffeeMachine {
// ...
Step 4. 상속으로 다양한 커피머신 만들기 (Inheritance)
커피머신을 상속하는 라떼머신을 만들어보자.
super를 통해 부모 클래스의 것을 가져다 쓸 수 있다.
※ A extends B = A는 B를 확장한다.
class LatteMachine extends CoffeeMachine {
private milk: number = 0;
constructor(beans: number, milk: number) {
super(beans);
this.milk = milk;
}
makeCoffee(shots: number): CoffeeCup {
const coffee = super.makeCoffee(shots);
return {
...coffee,
hasMilk: true,
};
}
}
Step 5. makeCoffee 함수로 다형성 이해하기 (Polymorphism)
makeCoffee 함수는 커피머신과 라떼머신 둘 다 갖고있다.
그러나 그 내용은 다르다. 이것이 다형성의 개념이다.
아래 forEach문은 커피머신이 만든 커피와와 라떼머신이 만든 커피를 각각 출력한다.
const machines = {
new CoffeeMachine(16),
new LatteMachine(16, 5),
};
machines.forEach(machine => {
console.log(machine.makeCoffee(1));
});
'TypeScript' 카테고리의 다른 글
[TypeScript] Type Alias와 Interface 비교 (0) | 2021.04.16 |
---|---|
[TypeScript] 제네릭을 사용하는 이유 (0) | 2021.04.15 |
[TypeScript] 유니온 타입은 언제 사용하는가? (0) | 2021.04.13 |
TypeScript에서 추가된 함수 기능들! (0) | 2021.04.13 |
Type Assertion(타입 단언)을 사용하는 이유 (0) | 2021.04.10 |