typescript에서의 Class는 ES6와 어떻게 다를까? 그리고 멤버변수 선언은 어떻게 대체할 수 있을까?
class Car {
constructor (color) {
this.color = color;
}
start() {
console.log("start");
}
}
const bmw = new Car("red");
JS에서는 위처럼 작성해도 아무런 문제가 없다. 그러나 TS에서는 this.color
부분에 color라는 프로퍼티가 Car에 없다고 경고가 뜬다.
이러한 경고는 먼저 멤버 변수를 선언해주는 것으로 해결 가능하다.
class Car {
color: string; // 먼저 선언을 해서 알려준다.
constructor (color: string) {
this.color = color;
}
start() {
console.log("start");
}
}
const bmw = new Car("red");
멤버 변수를 선언하지 않고 위 경고를 해결하는 방법이 있다.
바로 접근 제한자 중에서 public
, protected
을 쓰거나 readonly
를 활용하는 것!
접근 제한자 中
private
접근 제한자 중엔 private도 있는데 이를 제외하고 말한 이유는 위 경우를 해결하는 방법으로 보기 어렵기 때문이다.
왜냐하면 선언은 되었지만 읽히지 않는다고 뜨기 때문.이는 private의 성격 때문으로 보이며, 이것에 대해서는 차후 접근 제한자로 따로 떼어보자.
해결하는 방법은 알았지만 접근 제한자의 public과 protected의 차이는 무엇일까? 그리고 readonly를 쓰면 어떤 영향이 있을까?
이건 다음 포스팅에서 자세히 훑어보기로 하자.
static
을 활용하면 정적 멤버 변수를 만들어주는 것이 가능하다.
아래 예시에선 wheels를 static으로 선언해주었다.
class Car {
name: string = "car";
color: string;
static wheels = 4 // static 사용
constructor (color: string) {
this.color = color;
}
info() {
console.log(this.wheels); // 에러 발생
console.log(Car.wheels); // Class명 사용
}
}
class Bmw extends Car {
constructor (color: string) {
super(color);
}
showName() {
console.log(super.name);
}
}
const z4 = new Bmw("black");
console.log(z4.wheels); // 에러 발생
console.log(Car.wheels); // 에러 X
이러한 static선언 변수의 접근 방식은 this가 아니라 위처럼 해당 static이 있는 Class명으로 접근하는 것이다.
추상 클래스를 만드는 방법은 class앞에 abstract를 붙여주는 것이다.
abstract class Car { // 추상 클래스
name: string = "car";
color: string;
constructor (color: string) {
this.color = color;
}
start() {
console.log("start");
}
}
이렇게 만들어진 추상 클래스는 new
로 직접 사용하는 것은 불가하고, 상속을 통해 사용이 가능하다.
abstract class Car {
name: string = "car";
color: string;
constructor (color: string) {
this.color = color;
}
start() {
console.log("start");
}
}
const car = new Car("red"); // 에러발생
class Bmw extends Car { // 상속을 통해서 Car 사용
constructor (color: string) {
super(color);
}
showName() {
console.log(super.name);
}
}
const z4 = new Bmw("black");
abstract
를 이용해서 추상 메소드의 작성도 가능하다.
abstract class Car {
name: string = "car";
color: string;
constructor (color: string) {
this.color = color;
}
abstract doSomething(): void; // 추상 메소드
}
단 이때 주의할 점이 있다. 위에서 추상 class는 상속받아서 사용가능하다고 하였다.
그런데 이렇게 상속한 class안에 추상 메소드가 있는데 그냥 상속만 한다면?
이처럼 경고가 뜬다. 이는 말 그대로 추상적인 메소드만 있기 때문이다.
즉, 추상화란 개념이란 이름만 대략 설정할 뿐인 것이고 이것에 대한 기능은 상속받는 쪽에서 정의해줘야 한다는 것이다.
abstract class Car {
name: string = "car";
color: string;
constructor (color: string) {
this.color = color;
}
abstract doSomething(): void; // 추상 메소드
}
class Bmw extends Car {
constructor (color: string) {
super(color);
}
doSomething() { // 상속받은 쪽에서 정의
console.log("GO!")
}
}
이를 활용하면 상속 받는 수많은 객체가 이름은 동일하지만 다른 일을 하는 가지각색의 메소드를 지닐 수 있다.
이번에 Class에 대해 배우면서 사이드로 이것저것 많은 내용이 있어서 정리할게 많았던 것 같다. 글도 계속 쪼개고.. 한번에 글 세개를 썼네,, 워후😵