다형성
같은이름의 함수여도 동작이 다양할 수 있다.
- 인터페이스 구현 시
형식만 정해져있지 구현은 상속받은 쪽에서 하는 것이므로 행위는 다양할 수 있다.
- 클래스를 상속받아서 부모 클래스의 함수를 오버라이딩 하여도 다형성이 생긴다.
코드 예시
커피메이커 인터페이스
에는makeCoffee
라는 함수가 선언되어 있다.
커피머신
은 커피메이커 인터페이스를 구현한다.
라떼머신
과스윗머신
은 커피머신을 상속받으며, makeCoffee함수를 오버라이딩하여 다르게 구현하였다.
- 똑같은 이름의 makeCoffee 함수를 호출하여도, 셋의 결과물은 서로 다르다.
{ type CoffeeCup = { shots: number; hasMilk?: boolean; hasSugar?: boolean; }; interface CoffeeMaker { makeCoffee(shots: number): CoffeeCup; } class CoffeeMachine implements CoffeeMaker { private static BEANS_GRAMM_PER_SHOT: number = 7; // class level private coffeeBeans: number = 0; // instance (object) level constructor(coffeeBeans: number) { this.coffeeBeans = coffeeBeans; } static makeMachine(coffeeBeans: number): CoffeeMachine { return new CoffeeMachine(coffeeBeans); } fillCoffeeBeans(beans: number) { if (beans < 0) { throw new Error("value for beans should be greater than 0"); } this.coffeeBeans += beans; } clean() { console.log("cleaning the machine...🧼"); } private grindBeans(shots: number) { console.log(`grinding beans for ${shots}`); if (this.coffeeBeans < shots * CoffeeMachine.BEANS_GRAMM_PER_SHOT) { throw new Error("Not enough coffee beans!"); } this.coffeeBeans -= shots * CoffeeMachine.BEANS_GRAMM_PER_SHOT; } private preheat(): void { console.log("heating up... 🔥"); } private extract(shots: number): CoffeeCup { console.log(`Pulling ${shots} shots... ☕️`); return { shots, hasMilk: false, }; } makeCoffee(shots: number): CoffeeCup { this.grindBeans(shots); this.preheat(); return this.extract(shots); } } class CaffeLatteMachine extends CoffeeMachine { constructor(beans: number, public readonly serialNumber: string) { super(beans); } private steamMilk(): void { console.log("Steaming some milk... 🥛"); } makeCoffee(shots: number): CoffeeCup { const coffee = super.makeCoffee(shots); this.steamMilk(); return { ...coffee, hasMilk: true, }; } } class SweetCoffeeMaker extends CoffeeMachine { makeCoffee(shots: number): CoffeeCup { const coffee = super.makeCoffee(shots); return { ...coffee, hasSugar: true, }; } } const machines: CoffeeMaker[] = [ new CoffeeMachine(16), new CaffeLatteMachine(16, "1"), new SweetCoffeeMaker(16), new CoffeeMachine(16), new CaffeLatteMachine(16, "1"), new SweetCoffeeMaker(16), ]; machines.forEach((machine) => { console.log("-------------------------"); const coffee = machine.makeCoffee(1); console.log(coffee); }); }
