[TypeScript] Class - 추상 클래스

dev.galim·2023년 9월 14일
0

TypeScript

목록 보기
6/10

추상 클래스

→ 다른 클래스들이 파생될 수 있는 기초 클래스.

직접 인스턴스화 할 수 없음.

abstract 키워드는 추상 클래스나 추상 메소드를 정의할 때 사용됨.

추상 메소드는 클래스에는 구현되어 있지 않고, 파생된 클래스에서 구현해야 함.

  • 추상 클래스 내에서 추상으로 표시된 메소드는 구현을 포함하지 않으며, 파생된 클래스에서 구현이 필수
abstract class Animal {
	protected name: string;

	constructor(name: string) {
		this.name = name;
	}
	
	abstract makeSound(): void;
	
	move(): void {
		console.log("move!");
	}
}

class Dog extends Animal {
	constructor(name: string) {
		super(name); // 파생된 클래스의 생성자는 반드시 super()를 호출
	}
	makeSound(): void { // 반드시 파생된 클래스에서 구현 필수
		console.log(this.name + "멍멍!");
	}
}

const animal = new Animal("animal"); // Error, Animal 클래스는 추상 클래스이기 때문에 직접 선언하면 에러가 발생함.
const dog = new Dog("진돗개");

dog.makeSound(); // 진돗개 멍멍!
  • Animal 추상 클래스가 선언되어 있고 그 안에는 추상 메소드 makeSound()가 선언되어 있음. Animal 클래스는 추상 클래스이기 때문에 직접 선언하면 에러가 발생함.
  • Dog 클래스는 Animal 클래스를 부모 클래스로 상속받아 재사용하고 있음. 그렇기에 Dog 클래스는 Animal 클래스가 가지고 있는 추상 메소드Dog 클래스 안에서 반드시 재구현 해야 함.

추상 클래스를 활용한 디자인 패턴(Template Method Pattern)

- 디자인 패턴 → 프로그램의 일부분을 서브 클래스로 캡슐화해 전체 구조를 바꾸지 않고 특정 단계의 기능을 바꾸는 것.
- 전체적인 알고리즘은 상위 클래스에서 구현하고, 다른 부분은 하위 클래스에서 구현함.
- 전체 구조는 유사하지만 부분적으로 다른 구문으로 구성된 메소드의 코드 중복을 최소화 할 수 있음.

```jsx
abstract class Parent {
	// 템플릿 메소드 : 자식에서 공통적으로 사용하는 부분(someMethod)
	public do() {
		console.log("Parent에서 실행 - 상");
		this.hook(); // 훅 메소드 : Child에서 구현해야 할 부분
		console.log("Parent에서 실행 - 하");
	}
	abstract hook(): void
}

class Child extends Parent {
	hook(): void {
		console.log("Child");
	}
}

const chi;d = new Child();
child.do();

// 실행 결과
// Parent에서 실행 - 상
// Child
// Parent에서 실행 - 하
```

- Parent 추상 클래스에 훅이라는 이름을 가진 메소드를 선언함.
    
    `abstract hook(): void`
    
- Parent 클래스의 do 메소드에 추상 메소드를 호출하도록 함.
`this.hook();`
- `Child` 클래스에 `Parent` 클래스를 상속받아 추상 메소드인 `hook` 메소드를 재구현함.
abstract class Student {
  // 자식 class에서 공통적으로 사용하는 부분을 템플릿 메서드라 합니다.
  // study메소드를 템플릿 메소드로 만들어 주세요.
  public study() {
    console.log("공부 시작!");  
    // 자식 class에서 각자 다른 메소드가 구현되는 takeABreak 메소드를 구현해주세요.
    console.log("공부 종료!");
  }
}

// Alice, June, Chloe는 학생입니다. Student Class를 확장하세요.
class Alice {
  takeABreak() : void {
    console.log("잠자며 휴식!");
  }
}

class June {
  takeABreak() : void {
    console.log("커피 한잔하며 휴식!");
  }
}

class Chloe {
  takeABreak() : void {
    console.log("산책하며 휴식!");
  }
}

/**
공부 시작!
잠자며 휴식
공부 종료!
*/
const alice = new Alice();
alice.study();

/**
공부 시작!
커피 한잔하며 휴식
공부 종료!
*/
const june = new June();
june.study();

/**
공부 시작!
산책하며 휴식
공부 종료!
*/
const chloe = new Chloe();
chloe.study();
abstract class Student {
  public study() {
    console.log("공부 시작!");
    this.takeABreak();
    console.log("공부 종료!");
  }

  abstract takeABreak(): void;
}

class Alice extends Student {
  takeABreak(): void {
    console.log("잠자며 휴식!");
  }
}

class June extends Student {
  takeABreak(): void {
    console.log("커피 한잔하며 휴식!");
  }
}

class Chloe extends Student {
  takeABreak(): void {
    console.log("산책하며 휴식!");
  }
}

const alice = new Alice();
alice.study();

const june = new June();
june.study();

const chloe = new Chloe();
chloe.study();
profile
열심히 해볼게요

0개의 댓글