기존에 모던 javascript에서도 클래스가 있다는 것을 알고 있을 것이다. (모른다면 아래 게시글을 보고 어느 정도 익혀 오자)
이번 게시글에서는 Typescript가 지원하는 클래스는 역시 기반이 Javascript이기 때문에 Typescript에서 만의 고유한 확장 기능에 대해서만 정리하고자 한다.
1. 클래스 정의와 접근제한자
우선 접근 제한자에 대해 알아보자면 기존 모던 자바스크립트의 클래스에서도 접근 제한자가 존재하기는 했는데, 특수문자로 선언을 해줘야 하는 제약이 있었으나 타입 스크립트에서는 자바와 같이 클래스 기반 객체 지향 언어가 지원하는 접근 제한자 public, pivate, protected를 지원하며 의미 또한 동일하다.
접근 범위 | public | protected | private |
클래스 내부 | O | O | O |
자식 클래스 내부 | O | O | X |
클래스 인스턴스 | O | X | X |
클래스 정의 예제를 통해 좀 더 상세하게 알아보자.
▷ 예제 1) 클래스 정의
class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
talk() {
console.log(`this animal's name is ${this.name}`);
}
}
const animal = new Animal("Ruby");
animal.talk();
일반적으로 클래스를 정의하면 위와 같은 형식으로 정의를 하게 되는데,
모던 자바스크립트와의 차이점은 constructor 생성자를 통해 파라미터를 받을 경우 멤버 변수를 굳이 미리 선언해두지 않아도 사용이 가능했던 반면 typescript의 경우에는 타입 지정과 함께 미리 선언을 해둬야 한다.
(this로 접근해서 그렇지 생성자 내부에서만 사용하고자 한다면 굳이 미리 선언해둘 필요는 없다.)
그리고 앞서 접근 제한자에 대해 알아봤는데, 접근 제한자를 생략할 경우 자동적으로 public 접근 제한자로 지정된다.
▷ 예제 2) 접근 제한자 사용
class Animal {
constructor(public name: string, protected age: number, private breed: string) {
this.name = name;
this.age = age;
this.breed = breed;
}
protected talk() {
console.log(`this animal's name is ${this.name}`);
}
}
const animal = new Animal("Ruby", 2, 'tlrhfmwkqmwhd');
// error : 'talk' 속성은 보호된 속성이며 'Animal' 클래스 및 해당 하위 클래스 내에서만 액세스할 수 있습니다.
animal.talk();
class Dog extends Animal{
constructor(name: string, age: number, breed: string) {
super(name, age, breed);
this.talk();
console.log(this.age);
// error : 'breed' 속성은 private이며 'Animal' 클래스 내에서만 액세스할 수 있습니다.
console.log(this.breed);
}
}
// this.talk(): this animal's name is Ruby
// this.age: 5
const dog = new Dog("Ruby", 5, 'tlrhfmwkqmwhd');
접근 제한자는 멤버 변수 혹은 함수에서 사용이 가능하며, 생성자 파라미터를 접근 제한자로 선언해두고 받을 경우 암묵적으로 클래스 프로퍼티로 선언된다.
예제 코드를 보면 알겠지만 public이 아닌 이상 외부에서 접근이 불가능하고, 자식 클래스에서 protected 접근 제한자는 접근이 가능한 반면에 private은 접근이 불가능하다는 것을 알려주고 있다.
2. 추상 클래스
추상 클래스는 하나 이상의 추상 메서드를 포함하며 일반 메서드 역시 포함할 수 있다.
추상 클래스는 abstract 키워드를 사용하며, 직접 인스턴스를 생성할 수 없고 상속만을 위해 사용된다.
abstract class Animal {
// 추상 메소드
abstract makeSound(): void;
// 일반 메소드
move(): void {
console.log("move move move!");
}
}
// 직접 인스턴스를 생성할 수 없다.
// new Animal(); // error : 추상 클래스의 인스턴스를 만들 수 없습니다.
class Dog extends Animal {
// 추상 클래스를 상속한 클래스는 추상 클래스의 추상 메소드를 반드시 구현하여야 한다
makeSound(): void {
console.log("Doooooog~");
}
}
const dog = new Dog();
dog.makeSound();
dog.move();
단골 소재로 나오는 게 인터페이스와 추상 클래스의 차이점인데,
간단하게 보자면 인터페이스의 경우 모든 메서드가 추상 메서드이지만, 추상 클래스는 저런 식으로 일반 메서드를 포함할 수 있다는 점이다.
뭐 상속과 구현의 차이도 있겠지만 일단 그 정도만 알고 있으면 될 것 같다.
참고: https://www.typescriptlang.org/docs/handbook/2/classes.html
댓글