{
  type CoffeeCup = {
    shots: number;
    hasMilk: boolean;
  };

	*// interface - 추상화
  // public 한 멤버변수와 메소드만 선언 가능*
  interface CoffeeMakerA {
    makeCoffee(shots: number): CoffeeCup;
  }

  interface CoffeeMakerB {
    makeCoffee(shots: number): CoffeeCup;
    clean(): void;
  }
	*// 추상화로 만들어진 인터페이스나 부모 클래스에 추상화 하고자 하는 기능들이
  // 선언되어져 있어야 한다.*

  class CoffeeMaker {

    private static BEANS_GRANS_PER_SHOT = 7; *// static 변수는 변경 불가*
    private coffeeBeans: number = 0;

    private constructor(coffeeBeans: number) {
      this.coffeeBeans = coffeeBeans;
    }

    static makeMachine(coffeeBeans: number) {
      return new CoffeeMaker(coffeeBeans);
    }

		public fillCoffeeBeans(beans: number) {
      if (beans < 0) {
        throw new Error('beans not enoughf');
      }
      this.coffeeBeans += beans;
    }
		
    public makeCoffee(shots: number): CoffeeCup {
      if (this.coffeeBeans < shots * CoffeeMaker.BEANS_GRANS_PER_SHOT) {
        throw new Error('Not enough coffee beans!');
      }
      this.coffeeBeans -= shots * CoffeeMaker.BEANS_GRANS_PER_SHOT;
      return {
        shots: shots,
        hasMilk: false,
      }
    }
		
		public clean() {
      console.log("Coffee Cleaning~...✨");
    }
  }

	class CoffeeStoreA {
    constructor(private machine: CoffeeMakerA) {
      machine.makeCoffee(2);
    }
  }

  class CoffeeStoreB {
    constructor(private machine: CoffeeMakerB) {
      machine.makeCoffee(2);
      machine.clean();
    }
  }

  const maker2: CoffeeMakerA = CoffeeMaker.makeMachine(34);
  console.log(maker2.makeCoffee(2));

}