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

	*// public
	// private
	// protected*
  class CoffeeMaker {

    private static BEANS_GRANS_PER_SHOT = 7; *// private*
    private coffeeBeans: number = 0;         *// private*
		private time: number = 0;                *// private*

		*// getter -> 함수가 아니다.*
		get timer(): number {
      return this.time;
    }

		*// setter -> 함수가 아니다.*
    set timer(num: number) {
      this.time = num;
    }
	
		// ----------
    private constructor(coffeeBeans: number) { *// private*
      this.coffeeBeans = coffeeBeans;
    }
    // #1: private constructor
    static makeMachine(coffeeBeans: number) { *// public*
      return new CoffeeMaker(coffeeBeans);
    }
    // #1: return new className();
    // -> 이처럼 함수(메소드)를 통해서 객체 생성이 되어있는 경우라면
    //    생성자 생성 이용을 못하도록 막하놓는 경우 사용하는 방법이다.
    //    그래서 생성자에 private 을 붙여서 밖에서 객체 생성을 통한 생성자 접근을 막고
    //    클래스 내부 함수(메소드)를 통해 객체 생성을 통한 생성자 접근을 가능하게 만들어 놓는다.
		// ----------

		public fillCoffeeBeans(beans: number) {        *// public*
      if (beans < 0) {
        throw new Error('beans not enoughf');
      }
      this.coffeeBeans += beans;
    }
		
    public makeCoffee(shots: number): CoffeeCup {  *// public*
      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,
      }
    }
  }

	const maker = new CoffeeMaker(34);
	maker.fillCoffeeBeans(32);
  console.log(maker);

  maker.timer = 10;         *// setter*
  console.log(maker.timer); *// getter(readonly)*

}
*constructor(private coffeeBeans: number, public cups: number) {

}*

따로 멤버변수를 선언할 필요 없이 생성자 매개변수에 private, public 등 접근지정자와 함께 선언해 주면 멤버변수처럼 할당이 가능하다. 즉, 멤버변수이자 매게변수(인자) 가 된다.