dev.syw

접근 제어자와 readonly, 추상 클래스, 인터페이스 구현, 매개변수 프로퍼티를 익힌다.

클래스

TypeScript의 클래스는 JavaScript 클래스에 타입과 접근 제어 기능을 더한 것입니다. 객체 지향 코드를 안전하고 명확하게 작성할 수 있게 해 줍니다.

학습 목표

  • 클래스에 타입과 접근 제어자를 붙인다.
  • public/private/protected/readonly 를 구분한다.
  • 추상 클래스와 인터페이스 구현을 이해한다.
  • 매개변수 프로퍼티로 코드를 줄인다.

기본 클래스

필드에 타입을 선언하고 생성자에서 초기화합니다.

class User {
  name: string;
  age: number;

  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }

  greet(): string {
    return `안녕, ${this.name}!`;
  }
}

const u = new User('민수', 20);
u.greet();

접근 제어자

각 멤버가 어디서 접근 가능한지 지정합니다.

제어자접근 범위
public어디서나 (기본값)
private클래스 내부에서만
protected클래스 내부 + 자식 클래스
class Account {
  public owner: string;
  private balance: number;

  constructor(owner: string, balance: number) {
    this.owner = owner;
    this.balance = balance;
  }

  deposit(amount: number) {
    this.balance += amount; // 내부 접근 OK
  }
}

const acc = new Account('민수', 1000);
acc.owner;    // OK
acc.balance;  // ❌ private이라 외부 접근 불가

💡 TIP — JavaScript의 #필드 도 진짜 private을 제공합니다. TypeScript의 private 는 컴파일 단계 검사이고, # 는 런타임에도 보호됩니다. 둘 중 하나로 일관되게 쓰면 됩니다.

readonly

readonly 멤버는 선언이나 생성자에서만 값을 정할 수 있고 이후엔 못 바꿉니다.

class Circle {
  readonly pi = 3.14159;
  constructor(public readonly radius: number) {}
}

const c = new Circle(5);
c.radius = 10; // ❌ 읽기 전용

매개변수 프로퍼티

생성자 매개변수에 접근 제어자를 붙이면, 필드 선언과 할당을 한 번에 처리합니다. 보일러플레이트가 크게 줄어듭니다.

class Point {
  constructor(
    public x: number,
    public y: number,
  ) {}
}

// 위는 아래와 동일
class PointLong {
  public x: number;
  public y: number;
  constructor(x: number, y: number) {
    this.x = x;
    this.y = y;
  }
}

인터페이스 구현

implements 로 클래스가 특정 인터페이스의 모양을 따르도록 강제합니다.

interface Printable {
  print(): void;
}

class Document implements Printable {
  constructor(private text: string) {}

  print(): void {
    console.log(this.text);
  }
}

인터페이스에 선언된 멤버를 빠뜨리면 컴파일 오류가 납니다.

추상 클래스

abstract 클래스는 직접 인스턴스를 만들 수 없고, 자식이 반드시 구현해야 할 메서드를 정의합니다.

abstract class Shape {
  abstract area(): number;        // 자식이 구현해야 함

  describe(): string {            // 공통 구현은 제공 가능
    return `넓이는 ${this.area()}`;
  }
}

class Square extends Shape {
  constructor(private size: number) {
    super();
  }
  area(): number {
    return this.size ** 2;
  }
}

new Shape();        // ❌ 추상 클래스는 직접 생성 불가
new Square(4).area(); // 16

⚠️ 주의 — 인터페이스는 "모양"만 정의하고 구현이 없습니다. 추상 클래스는 공통 구현을 함께 제공할 수 있다는 점이 다릅니다. 공유할 로직이 있으면 추상 클래스, 순수 계약만 필요하면 인터페이스를 고르세요.

요약

  • 클래스 멤버에 타입과 public/private/protected 접근 제어자를 붙인다.
  • readonly 는 초기화 후 변경을 막는다.
  • 매개변수 프로퍼티로 필드 선언·할당을 한 줄에 끝낸다.
  • implements 로 인터페이스 계약을, abstract 로 자식이 구현할 골격을 강제한다.

댓글 0

TypeScript” 강좌에 대한 댓글입니다.

댓글을 작성하려면 로그인이 필요합니다.