ES6 클래스는 클래스{}에 메소드()만을 포함할 수 있다.
클래스 내부에 클래스 프로퍼티를 선언할 수 없고, 생성자 내부에서 클래스 this.프로퍼티를 선언하고 초기화한다.
// JavaScript(ES6)
class Person {
constructor(name) {
// 클래스 프로퍼티
this.name = name;
}
// 클래스 메서드
walk() {
console.log(`${this.name} is walking.`);
}
}
이 클래스를 타입스크립트로 바꿔보면 클래스 프로퍼티만 수정하면 된다!
// TypeScript
class Person {
// 클래스 프로퍼티를 사전에 선언
public name: string;
constructor(name: string) {
// 클래스 프로퍼티에 값을 할당
this.name = name;
}
walk() {
console.log(`${this.name} is walking.`);
}
}
타입스크립트에만 있는 개념이다.
class Parent {
// 여기서 접근제한자를 선언해도 되지만, 생성자에서도 가능하다.
// public x: string;
protected y: string;
private z: string;
// 접근제한자를 생성자에서도 선언할 수 있다. (public)
constructor(public x: string, y: string, z: string, m: string) {
// public, protected, private 접근 제한자 모두 클래스 내부에서 참조 가능.
// 접근제한자를 선언한 적이 없는 매개변수 m은 생성자 내부에서만 유효한 지역 변수이다.
this.x = x;
this.y = y;
this.z = z;
// this.m 은 불가능하다!
console.log('parameter m :', m);
}
}
const parent = new Parent('x', 'y', 'z', 'm');
// public 접근 제한자는 클래스 인스턴스를 통해 클래스 외부에서 참조 가능
console.log(parent.x);
// protected 접근 제한자는 클래스 인스턴스를 통해 클래스 외부에서 참조 불가능!
console.log(parent.y);
// 에러: Property 'y' is protected and only accessible within class 'Parent' and its subclasses.
// private 접근 제한자는 클래스 인스턴스를 통해 클래스 외부에서 참조 불가능!
console.log(parent.z);
// 에러: Property 'z' is private and only accessible within class 'Parent'.
console.log(parent.m);
// 에러: Property 'm' does not exist on type 'Parent'.
class Child extends Parent {
constructor(x: string, y: string, z: string, m:string) {
super(x, y, z, m);
// public 접근 제한자는 자식 클래스 내부에서 참조 가능
console.log(this.x);
// protected 접근 제한자는 자식 클래스 내부에서 참조 가능
console.log(this.y);
// private 접근 제한자는 자식 클래스 내부에서 참조 불가능!
console.log(this.z);
// 에러: Property 'z' is private and only accessible within class 'Parent'.
}
}
타입스크립트에만 있는 개념이고, interface와 type 선언시에도 사용할 수 있는 키워드이다.
클래스에서 readonly가 선언된 클래스 프로퍼티는 선언 시 또는 생성자 내부에서만 값을 할당할 수 있다. 이 특징을 이용해서 상수를 활용한다.
class Abc {
private readonly MAX_LEN: number = 5;
private readonly MSG: string;
constructor() {
this.MSG = 'hello';
}
log() {
this.MAX_LEN = 10; // 에러: Cannot assign to 'MAX_LEN' because it is a constant or a read-only property.
this.MSG = 'Hi'; // 에러: Cannot assign to 'MSG' because it is a constant or a read-only property.
// 읽기는 가능
console.log(`MAX_LEN: ${this.MAX_LEN}`); // MAX_LEN: 5
console.log(`MSG: ${this.MSG}`); // MSG: hello
}
}
new Abc().log();
자바스크립트에도 있는 개념으로 인스턴스(객체)를 통해서는 클래스 내부 메서드에 접근하지 못하고, 클래스 자체를 통해서만 접근 가능하다.
타입스크입트에서는 static 키워드를 클래스 프로퍼티에도 사용할 수 있다.
class Abc {
// 생성된 인스턴스의 갯수
static instanceCounter = 0;
constructor() {
Foo.instanceCounter++;
}
}
var obj1 = new Abc();
var obj2 = new Abc();
// obj1이나 obj2를 통해 접근하지 않고 클래스를 통해 접근
console.log(Abc.instanceCounter); // 2
타입스크립트에만 있는 개념이고 객체를 생성하지 못하는 클래스다!
다른 클래스에서 상속을 받아야 구현할 수 있으며, 추상 메서드(abstract)는 상속받는 클래스에서 필수로 구현해야 한다.
abstract class Animal {
// 상속받는 클래스에서 반드시 구현해야 하는 abstract 메서드
abstract speak(): void;
listen(): void {
console.log("듣는중..")
}
}
class Person extends Animal {
speak(): void {
console.log("말로 표현해야 압니다.")
}
watch(): void {
console.log("관찰중..")
}
}
const jenny = new Animal() // 에러: Cannot create an instance of an abstract class.
const jane = new Person()
jane.listen() // "듣는중.."
jane.speak() // "말로 표현해야 압니다."
jane.watch() // "관찰중.."
참고한 사이트들
모던 자바스크립트 Deep Dive
캡틴판교님의 타입스크립트 핸드북