타입스크립트 교재 · 8편 / 20편

클래스 + 접근 제어자 — public·private·protected

class 에 타입 붙이기, 접근 제어, 생성자 단축 문법, abstract, implements.

기초읽는 시간 7분2026-05-17
TS 클래스의 public/private/protected 접근 제어자가 색상으로 구분된 도식

JS 의 class 위에 TS 가 추가하는 것은 두 가지 — 필드/메서드에 타입, 그리고 접근 제어자(public/private/protected). 그 위에 abstract, implements, 생성자 단축 같은 편의 문법이 얹힙니다. 8편은 OOP 색이 진한 코드를 다룰 때 필요한 모두를 정리합니다.

기본 — 필드와 메서드 타입

class User {
  // 필드 선언 + 타입
  id: number;
  name: string;
  active: boolean = true;       // 기본값

  // 생성자
  constructor(id: number, name: string) {
    this.id = id;
    this.name = name;
  }

  // 메서드
  greet(): string {
    return `Hi, ${this.name}!`;
  }
}

const u = new User(1, "준성");
u.greet();              // "Hi, 준성!"

생성자 단축 — parameter properties

// 위 코드를 한 번에 — 매개변수에 접근 제어자
class User {
  active: boolean = true;
  constructor(public id: number, public name: string) {}
  // 자동으로 this.id = id, this.name = name 됨
}

// 더 자주 쓰는 패턴 — readonly 와 함께
class User {
  constructor(
    public readonly id: number,
    public name: string,
    private password: string,
  ) {}
}

일일이 this.x = x 안 써도 되니까 훨씬 짧아집니다. TS-특유의 문법으로, JS 만 쓰는 코드에서는 안 보입니다.

접근 제어자 — public·private·protected

제어자접근 가능 위치런타임 강제
public (기본)어디서나
private같은 클래스 안에서만컴파일 시점만 (TS)
protected자신 + 자식 클래스컴파일 시점만 (TS)
#field (ES2022)같은 클래스 안에서만예 (JS 표준)
class Account {
  public balance: number = 0;          // 외부 접근 OK
  private secret: string = "...";      // 내부만
  protected log() { ... }              // 자신/자식만

  // ES2022 표준 — 진짜 private (런타임 강제)
  #pin: string = "1234";
}

const a = new Account();
a.balance;        // OK
a.secret;         // ❌ TS 컴파일 에러 (런타임에는 동작)
a.#pin;           // ❌ SyntaxError (런타임 강제)

TS private 의 한계. TS 의 private 는 컴파일 시점에만 체크됩니다. 런타임에는 일반 속성 — a["secret"] 같은 우회 접근 가능. 진짜 비공개가 필요하면 ES2022 의 #field (해시 프리픽스) 를 쓰세요. 단, IE 등 옛 환경은 미지원.

상속 — extends 와 super

class Animal {
  constructor(public name: string) {}
  speak(): string { return "..."; }
}

class Dog extends Animal {
  constructor(name: string, public breed: string) {
    super(name);                       // 부모 생성자 호출 필수
  }
  speak(): string {                    // 오버라이드
    return `${this.name} 짖기!`;
  }
}

const d = new Dog("초코", "리트리버");
d.speak();         // "초코 짖기!"

// override 키워드 (5.0+ noImplicitOverride 권장)
class Cat extends Animal {
  override speak(): string {
    return `${this.name} 야옹`;
  }
}

abstract — 직접 인스턴스화 못하는 베이스

abstract class Shape {
  abstract area(): number;             // 자식이 반드시 구현

  // 공통 메서드는 그대로 가짐
  describe(): string {
    return `면적 ${this.area()}`;
  }
}

class Circle extends Shape {
  constructor(public radius: number) { super(); }
  area(): number { return Math.PI * this.radius ** 2; }
}

new Shape();          // ❌ Cannot create an instance of an abstract class
new Circle(5);        // OK

implements — 인터페이스를 만족하는 클래스

interface Comparable<T> {
  compareTo(other: T): number;
}

class Version implements Comparable<Version> {
  constructor(public major: number, public minor: number) {}
  compareTo(other: Version): number {
    return this.major - other.major || this.minor - other.minor;
  }
}

implements 는 "이 모양을 반드시 가져야" 라는 강제. 인터페이스 자체는 런타임에 사라지므로 부하 0. 여러 인터페이스를 implements 도 가능: class X implements A, B, C.

readonly · getter/setter

class Config {
  readonly version: string = "1.0";    // 한 번 정해지면 변경 금지

  // 정적
  static readonly MAX_RETRY = 3;

  // getter/setter
  private _name: string = "";
  get name(): string { return this._name; }
  set name(v: string) {
    if (!v) throw new Error("name 비울 수 없음");
    this._name = v;
  }
}

클래스 vs 함수 + 객체 — 언제 클래스?

실전 가이드. 다음 중 2개 이상 해당하면 클래스, 아니면 함수 + 객체:

· 상태(필드) 가 있다.

· 같은 모양의 인스턴스가 여러 개 만들어진다.

· 상속·다형성이 자연스럽다.

· implements 로 인터페이스 강제가 의미 있다.

한 가지만 해당하면 함수 + 클로저 + 객체 리터럴 조합이 더 가볍습니다.

9편 — 모듈 시스템

ESM / CJS, import·export, declaration 파일과 paths 옵션.

📚 쉽게 배우는 타입스크립트 교재
이전: 7편 enum · 현재: 8편 (기초) · 다음 → 9편 모듈 · 진행: 8/20

© 2026 주나이테크(주) @JUNAITECH