TypeScript 클래스
타입스크립트 클래스
자바스크립트는 애초에 프로토타입기반을 이용해 상속을 구현합니다.
ES6 에 존재하는 class 키워드를 이용해 구현할 수 있습니다. 타입스크립트도 이와 동일하게 class 키워드를 이용합니다.
1. 클래스 키워드
ES6 를 다루어보셨다면 기존에 생각했던 것과 동일합니다. class 키워드 뒤에 클래스 이름을 적어줍니다.
class Button {
constructor() {
// ...
}
}
2. 생성자
클래스 기반 언어들에서는 생성자를 통해 멤버들을 초기화시켜줬습니다. ES6 에서도 동일하게 this. 을 이용하였던것이 생각납니다.
타입스크립트도 동일한데 다만, 사전에 등록되지 않은 프로퍼티를 초기화하려하면 에러를 내뱉습니다.
class Button {
constructor(name: string) {
this.name = name; // Error!
// TS2339: Property 'name' does not exist on type 'Button'.
}
}
다음으로 만들어야합니다.
class Button {
name: string;
constructor(name: string) {
this.name = name;
}
}
해당 클래스의 프로퍼티를 미리 작성해줘야 합니다.
3. 상속
ES6 문법에서 사용하던 extends 키워드를 동일하게 사용합니다.
class Input {
name: string;
constructor(name: string) {
this.name = name;
}
inputName() {
console.log(`input name is ${ this.name }`);
}
}
class Button extends Input {
constructor(name: string) {
super(name);
}
}
const button = new Button('click me');
button.inputName(); // input name is click me
현재 상속계층은 Button 이 Input 을 상속받고있습니다.
하위클래스에서 constructor 를 정의하고싶다면 반드시 상위클래스의 constructor 를 호출해야만합니다. super(name) 을 보면 매개변수도 동일하게 전달하는것을 확인할 수 있습니다. 그리고 마지막에 inputName() 을 호출하여 콘솔로그에 찍히는 것도 볼 수 있습니다.
4. 오버라이드
타입스크립트에서도 오버라이드를 구현할 수 있습니다.
오버라이드(Override)란?
상위 클래스에서 정의한 메서드를 자식클래스에서 재정의 하는 것.
class Input {
name: string;
constructor(name: string) {
this.name = name;
}
inputName() {
console.log(`input name is ${ this.name }`);
}
}
class Button extends Input {
constructor(name: string) {
super(name);
}
inputName() {
console.log(`button name is ${ this.name }`);
}
}
const button = new Button('kikiki');
button.inputName(); // button name is kikiki
inputName() 메서드를 하위클래스인 Button 에서 오버라이드 하여 호출했습니다. 출력결과가 다른것을 확인할 수 있습니다.
5. 접근제어자
public : 디폴트값, 어디에서나 접근가능.
protected : 상속받은 하위클래스만 접근가능.
private : 선언한 클래스 내에서만 접근가능.
5- 1 public
별도로 프로퍼티나 메서드 앞에 추가해주지않아도 됩니다. 명시적으로 다음과 같이 수정할 수 있습니다.
class Input {
public name: string;
public constructor(name: string) {
this.name = name;
}
public inputName() {
console.log(`input name is ${ this.name }`);
}
}
class Button extends Input {
public constructor(name: string) {
super(name);
}
public inputName() {
console.log(`button name is ${ this.name }`);
}
}
5- 2 protected
선언한 클래스를 포함해 상속받는 하위클래스에서만 접근 가능합니다.
class Input {
protected name: string;
constructor(name: string) {
this.name = name;
}
protected inputName() {
console.log(`input name is ${ this.name }`);
}
}
const input = new Input('input');
// console.log(input.inputName()); Error!
// TS2445: Property 'inputName' is protected and only accessible within class 'Input' and its subclasses.
public 인 constructor() 를 통해 인스턴스를 생성했지만 protected 접근제어자가 붙은 inputName() 는 외부에서 호출불가능한것을 볼 수 있습니다.
constructor() 에 protected가 붙는다면 해당 클래스는 바로 인스턴스화 될 수 없습니다. 상속받은 하위클래스에서 super 를 이용해 호출할 수 있습니다.
class Input {
protected name: string;
protected constructor(name: string) {
this.name = name;
}
protected inputName() {
console.log(`input name is ${ this.name }`);
}
}
class Button extends Input {
constructor(name: string) {
super(name);
}
inputName() {
console.log(`button name is ${ this.name }`);
}
}
const button: Input = new Button('button');
5-3 private
선언한 클래스 내에서만 접근이 가능합니다. 보통 private 키워드가 붙은 프로퍼티는 _(언더바) 를 붙이는것이 통상적이라고 합니다. 이후에 외부에서 접근을 할 시에는 get / set 을 이용합니다.
class Input {
private _name: string;
protected constructor(name: string) {
this._name = name;
}
get name(): string {
return this._name;
}
set name(name: string) {
this._name = name;
}
}
class Button extends Input {
constructor(name: string) {
super(name);
// console.log(this._name); Error!
// TS2341: Property '_name' is private and only accessible within class 'Input'.
}
}
const button = new Button('my Button');
// get 호출
console.log(`button name is ${ button.name }`); // button name is my Button
// set 호출
button.name = 'my Button2';
// get 호출
console.log(`button name is ${ button.name }`); // button name is my Button2