🌈 코딩앙마의
TypeScript 강좌
수강 후, 이해한 내용을 정리한 글입니다.
JavaScript에서 class 작성 시, 멤버 변수를 미리 선언하지 않아도 된다.
class Car{
constructor(color) {
this.color = color;
}
start() {
console.log("start");
}
}
const bmw = new Car("red");
하지만 TypeScript에서 class 작성 시, 아래 3가지 중 하나를 해주어야 한다.
// 멤버 변수 미리 선언
color: string;
class Car{
constructor(color: string) {
this.color = color;
}
start() {
console.log("start");
}
}
const bmw = new Car("red");
// public
class Car{
constructor(public color: string) {
this.color = color;
}
start() {
console.log("start");
}
}
const bmw = new Car("red");
// readonly
class Car{
constructor(readonly color: string) {
this.color = color;
}
start() {
console.log("start");
}
}
const bmw = new Car("red");
접근 제한자는 클래스, 메서드 및 기타 멤버의 접근성을 설정하는 객체 지향 언어의 키워드이다. 캡슐화에 용이하게 사용된다. 아래는 접근 제한자의 종류이다.
해당 클래스 내부
, 자식 클래스
, 인스턴스
에서 접근 가능해당 클래스 내부
, 자식 클래스
에서 접근 가능해당 클래스 내부
에서 접근 가능// 1️⃣ public
class Car {
public name: string = "car"; // public 생략 가능
color: string;
constructor(color: string) {
this.color = color;
}
start() {
console.log("start");
console.log(this.name); // ✅ 해당 클래스 내부에서 접근 가능
}
}
class Bmw extends Car {
constructor(color: string) {
super(color);
}
showName() {
console.log(this.name); // ✅ 자식 클래스에서 접근 가능
}
}
const z4 = new Bmw("black");
console.log(z4.name); // ✅ 인스턴스에서 접근 가능
// 2️⃣ protected
class Car {
protected name: string = "car";
color: string;
constructor(color: string) {
this.color = color;
}
start() {
console.log("start");
console.log(this.name); // ✅ 해당 클래스 내부에서 접근 가능
}
}
class Bmw extends Car {
constructor(color: string) {
super(color);
}
showName() {
console.log(this.name); // ✅ 자식 클래스에서 접근 가능
}
}
const z4 = new Bmw("black");
console.log(z4.name); // ❌ Error! 인스턴스에서 접근 불가
// 3️⃣ private
// 1) private으로 작성
class Car {
private name: string = "car";
color: string;
constructor(color: string) {
this.color = color;
}
start() {
console.log("start");
console.log(this.name); // ✅ 해당 클래스 내부에서 접근 가능
}
}
class Bmw extends Car {
constructor(color: string) {
super(color);
}
showName() {
console.log(this.name); // ❌ Error! 자식 클래스에서 접근 불가
}
}
const z4 = new Bmw("black");
console.log(z4.name); // ❌ Error! 인스턴스에서 접근 불가
// 2) #으로 작성 (⭐️ 부분 변경)
class Car {
#name: string = "car"; // ⭐️
color: string;
constructor(color: string) {
this.color = color;
}
start() {
console.log("start");
console.log(this.#name); // ✅ 해당 클래스 내부에서 접근 가능 // ⭐️
}
}
class Bmw extends Car {
constructor(color: string) {
super(color);
}
showName() {
console.log(this.#name); // ❌ Error! 자식 클래스에서 접근 불가 // ⭐️
}
}
const z4 = new Bmw("black");
console.log(z4.name); // ❌ Error! 인스턴스에서 접근 불가
readonly 키워드가 붙은 프로퍼티는 수정이 불가능하다. 수정하기 위해서는 constructor 안에서 해당 작업을 수행해 주어야 한다.
// 📍 직접 수정 불가 예시
class Car {
readonly name: string = "car";
color: string;
constructor(color: string) {
this.color = color;
}
start() {
console.log("start");
console.log(this.name);
}
}
class Bmw extends Car {
constructor(color: string) {
super(color);
}
showName() {
console.log(this.name);
}
}
const z4 = new Bmw("black");
console.log(z4.name);
z4.name = "My car" // ❌ Error! 수정 불가
// 📍 constructor 내부에서 수정 (⭐️ 부분 변경)
class Car {
readonly name: string = "car";
color: string;
constructor(color: string, name) { // ⭐️
this.color = color;
this.name = name; // ⭐️
}
start() {
console.log("start");
console.log(this.name);
}
}
class Bmw extends Car {
constructor(color: string, name) { // ⭐️
super(color, name); // ⭐️
}
showName() {
console.log(this.name);
}
}
const z4 = new Bmw("black", "My car"); // ⭐️
console.log(z4.name);
static으로 정적 멤버 프로퍼티를 만들 수 있다. 정적 멤버 프로퍼티는 class명으로 접근한다.
// 📍 잘못된 예시
class Car {
readonly name: string = "car";
color: string;
static wheels = 4;
constructor(color: string, name) {
this.color = color;
this.name = name;
}
start() {
console.log("start");
console.log(this.name);
console.log(this.wheels); // ❌ Error!
}
}
class Bmw extends Car {
constructor(color: string, name) {
super(color, name);
}
showName() {
console.log(this.name);
}
}
const z4 = new Bmw("black", "My car");
console.log(z4.name);
console.log(z4.wheels); // ❌ Error!
// 📍 옳은 예시
class Car {
readonly name: string = "car";
color: string;
static wheels = 4;
constructor(color: string, name) {
this.color = color;
this.name = name;
}
start() {
console.log("start");
console.log(this.name);
console.log(Car.wheels); // ✅ class명으로 접근
}
}
class Bmw extends Car {
constructor(color: string, name) {
super(color, name);
}
showName() {
console.log(this.name);
}
}
const z4 = new Bmw("black", "My car");
console.log(z4.name);
console.log(Car.wheels); // ✅ class명으로 접근
1) 추상 클래스
new를 이용해서 인스턴스를 만들 수 없다. 오직 상속을 통해서만 사용이 가능하다.
abstract class Car{ // ⭐️
color: string;
constructor(color: string) {
this.color = color;
}
start() {
console.log("start");
}
}
const car = new Car("red"); // ❌ Error! new로 인스턴스 생성 불가
class Bmw extends Car { // ✅ 상속을 통해서만 사용 가능
constructor(color: string) {
super(color);
}
}
const z4 = new Bmw("black");
2) 추상 메서드
추상 클래스 내부의 추상 메서드는 반드시 상속받은 클래스에서 구현해 주어야 한다. 따라서 상속받은 클래스 내부에는 해당 추상 메서드가 반드시 존재하지만 구체적인 기능은 상이할 수 있다.
// 📍 잘못된 예시
abstract class Car{
color: string;
constructor(color: string) {
this.color = color;
}
start() {
console.log("start");
}
abstract doSomething(): void; // ⭐️
}
class Bmw extends Car { // ❌ Error! Bmw에 doSomething이 구현되지 않음
constructor(color: string) {
super(color);
}
}
const z4 = new Bmw("black");
// 📍 옳은 예시
abstract class Car{
color: string;
constructor(color: string) {
this.color = color;
}
start() {
console.log("start");
}
abstract doSomething(): void; // ⭐️
}
class Bmw extends Car { // ✅ Bmw에 doSomething 구현
constructor(color: string) {
super(color);
}
doSomething() {
alert(3);
}
}
const z4 = new Bmw("black");