TypeScript

TypeScript로 이해하는 객체지향

DevPanda 2021. 4. 14. 23:24

 

객체지향적으로 커피머신을 만들어보자.

 

목표

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));
});