TypeScript

[TypeScript] 클래스와 OOP(Object-Oriented Programming)

hoazzinews 2025. 10. 28. 10:52

TypeScript는 ECMAScript 2015(ES6)에서 도입된 클래스(Class) 문법을 기반으로, 더 강력한 객체지향 프로그래밍(OOP) 기능을 제공합니다.

클래스는 객체의 청사진(blueprint) 으로, 데이터(속성)와 동작(메서드)을 하나의 단위로 묶어 코드의 재사용성과 유지보수성을 높입니다.

 

1 클래스의 기본 구조

TypeScript에서의 클래스 선언은 JavaScript와 유사하지만,
속성과 생성자에 명시적인 타입 선언을 할 수 있습니다.

class User {
  name: string;
  age: number;

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

  introduce(): string {
    return `안녕하세요, ${this.name}입니다. 나이는 ${this.age}살입니다.`;
  }
}

const user1 = new User("Alice", 30);
console.log(user1.introduce());

 

  • constructor는 인스턴스 생성 시 자동으로 호출됩니다.
  • 속성과 메서드 모두 타입을 지정할 수 있습니다.
  • TypeScript는 생성자에서 할당되지 않은 속성이 있으면 오류를 발생시킵니다.

 

2. 접근 제어자 (public, private, protected)

TypeScript에서는 클래스 멤버의 접근 범위를 제어하기 위해
접근 제어자(Access Modifier) 를 제공합니다.

제어자 접근 범위 설명
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): void {
    this.balance += amount;
  }

  getBalance(): number {
    return this.balance;
  }
}

const acc = new Account("Alice", 1000);
acc.deposit(500);
console.log(acc.getBalance()); // 1500
// acc.balance 접근 불가 (private)

※ private을 활용하면 클래스 외부에서 직접 데이터가 수정되는 것을 방지할 수 있습니다.
    즉, 데이터 은닉(Encapsulation) 이 가능합니다.

 

3. 클래스 상속과 super

TypeScript는 extends 키워드를 통해 클래스 상속을 지원합니다.

class Animal {
  constructor(public name: string) {}
  move(distance: number) {
    console.log(`${this.name}가 ${distance}m 이동했습니다.`);
  }
}

class Dog extends Animal {
  bark() {
    console.log("멍멍!");
  }
}

const dog = new Dog("바둑이");
dog.bark(); // 멍멍!
dog.move(10); // 바둑이가 10m 이동했습니다.

자식 클래스에서 부모의 생성자를 호출하려면 super()를 사용해야 합니다.

class Bird extends Animal {
  constructor(name: string, public wings: number) {
    super(name);
  }
}

※ super는 부모 클래스의 생성자나 메서드에 접근할 때 사용합니다.

 

4. 추상 클래스(Abstract Class)

추상 클래스(Abstract Class) 는 인스턴스를 직접 생성할 수 없고,
상속을 통해 구체화해야 하는 클래스를 의미합니다.

abstract class Shape {
  constructor(public name: string) {}
  abstract getArea(): number; // 하위 클래스에서 반드시 구현해야 함
}

class Rectangle extends Shape {
  constructor(name: string, private width: number, private height: number) {
    super(name);
  }

  getArea(): number {
    return this.width * this.height;
  }
}

const rect = new Rectangle("직사각형", 10, 20);
console.log(rect.getArea()); // 200
  • 추상 클래스는 abstract 키워드를 사용합니다.
  • abstract 메서드는 구체적인 구현 없이 선언만 존재합니다.
  • 상속받은 클래스는 반드시 해당 메서드를 구현해야 합니다.

이 기능은 공통 인터페이스를 정의하면서, 구체적인 구현은 자식 클래스에 위임할 때 유용합니다.
(예: Repository, Service 추상 클래스 설계 등)

 

5. 인터페이스와 클래스의 결합 (implements)

클래스는 implements 키워드를 사용하여 인터페이스를 구현할 수 있습니다.
이 방식은 클래스가 특정한 형태를 따르도록 강제합니다.

interface Logger {
  log(message: string): void;
}

class ConsoleLogger implements Logger {
  log(message: string): void {
    console.log(`[LOG] ${message}`);
  }
}

const logger = new ConsoleLogger();
logger.log("TypeScript 클래스 학습 중입니다!");

※ React의 useReducer, context provider, 또는 DI(의존성 주입) 구조 설계 시
     이런 방식으로 공통 인터페이스를 정의하고 클래스별 구현을 분리하는 패턴이 자주 사용됩니다.

class DataStore<T> {
  private data: T[] = [];

  add(item: T): void {
    this.data.push(item);
  }

  getAll(): T[] {
    return this.data;
  }
}

const numberStore = new DataStore<number>();
numberStore.add(10);
numberStore.add(20);

const stringStore = new DataStore<string>();
stringStore.add("A");
stringStore.add("B");

console.log(numberStore.getAll()); // [10, 20]
console.log(stringStore.getAll()); // ["A", "B"]

 

  • <T>는 타입 매개변수로, 클래스가 사용할 데이터 타입을 외부에서 지정합니다.
  • 이를 통해 타입 안정성을 유지하면서도 범용적인 로직을 구현할 수 있습니다.

※ 이 패턴은 React의 useState<T>(), useReducer<T>() 등에서도 동일하게 사용됩니다.

 

6. 정리

 

  • 클래스는 TypeScript의 객체지향 프로그래밍(OOP)을 위한 핵심 구조입니다.
  • 접근 제어자를 통해 데이터 은닉과 안전성을 확보할 수 있습니다.
  • extends와 super를 이용해 상속 구조를 설계할 수 있습니다.
  • 추상 클래스와 인터페이스를 함께 활용하면 유연한 설계가 가능합니다.
  • 제네릭 클래스는 타입 안정성을 유지하며 재사용성을 극대화합니다.

 

다음 섹션에서는 "제네릭 (Generics) – 다양한 데이터 타입을 하나의 로직으로 처리"하기 위한 TypeScript 제네릭의 핵심 개념과 실무 활용 패턴을 학습합니다.

 

 

 

 

반응형