본문 바로가기
카테고리 없음

클래스와 객체지향 프로그래밍 – TypeScript에서 클래스 사용법 (14강)

by mystory55776 2025. 5. 15.

클래스와 객체지향 프로그래밍 – TypeScript에서 클래스 사용법 (14강)

**TypeScript**는 **객체지향 프로그래밍(OOP)**을 지원하는 강력한 기능을 제공합니다. 그 중에서 **클래스(class)**는 객체지향 프로그래밍의 핵심 개념으로, 재사용 가능하고 관리 가능한 코드를 작성하는 데 중요한 역할을 합니다. 이번 강의에서는 **TypeScript에서 클래스 사용법**과 **객체지향 프로그래밍**의 기본 개념을 살펴보고, 이를 TypeScript에서 어떻게 적용할 수 있는지 알아보겠습니다.

객체지향 프로그래밍(OOP) 개요

**객체지향 프로그래밍(OOP)**은 프로그램을 객체라는 단위로 구성하고, 이 객체들이 서로 상호작용하면서 프로그램을 완성하는 방식입니다. OOP의 주요 특징은 다음과 같습니다:

  • 캡슐화(Encapsulation): 객체의 상태(속성)와 동작(메서드)을 하나의 단위로 묶어 외부에서 직접 접근하지 못하게 보호하는 개념
  • 상속(Inheritance): 부모 클래스의 속성과 메서드를 자식 클래스가 상속받아 재사용하는 개념
  • 다형성(Polymorphism): 동일한 메서드가 다른 클래스에서 다르게 동작하도록 구현하는 개념
  • 추상화(Abstraction): 복잡한 시스템을 간단하게 표현하기 위해 불필요한 세부 사항을 숨기는 개념

TypeScript는 이러한 객체지향 프로그래밍의 개념을 지원하며, **클래스**를 통해 코드의 구조를 보다 명확하고 효율적으로 작성할 수 있습니다.

TypeScript에서 클래스 사용법

TypeScript에서 클래스는 **`class`** 키워드를 사용하여 정의할 수 있습니다. 클래스는 객체를 생성하기 위한 **청사진**으로, 클래스 내부에 **속성**과 **메서드**를 정의할 수 있습니다.

1. 클래스 정의와 생성자(Constructor)

클래스를 정의할 때, 클래스 내부에 **속성**(프로퍼티)과 **메서드**를 정의할 수 있으며, 클래스의 인스턴스를 만들기 위한 **생성자(constructor)**를 사용할 수 있습니다. 생성자는 클래스가 인스턴스화될 때 자동으로 호출되는 특수한 메서드입니다.

class Person {
  // 속성 정의
  name: string;
  age: number;

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

  // 메서드 정의
  greet() {
    console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
  }
}

// 인스턴스 생성
const person1 = new Person("John", 30);
person1.greet();  // "Hello, my name is John and I am 30 years old."

위 예제에서는 **Person**이라는 클래스를 정의하고, 생성자에서 **name**과 **age**를 인자로 받아 초기화합니다. 이후 **greet** 메서드를 통해 인사하는 기능을 구현합니다. **new Person("John", 30)**으로 클래스를 인스턴스화하고, **greet()** 메서드를 호출하여 객체의 속성값을 출력할 수 있습니다.

2. 접근 제어자 (Access Modifiers)

TypeScript에서는 클래스 속성과 메서드에 접근 제어자를 사용할 수 있습니다. 기본적으로 TypeScript는 **public**, **private**, **protected**와 같은 접근 제어자를 지원합니다. 이를 통해 객체의 속성이나 메서드에 대한 접근을 제한하거나 허용할 수 있습니다.

  • public: 기본 접근 제어자. 모든 클래스 외부에서 접근 가능합니다.
  • private: 클래스 외부에서 접근할 수 없으며, 오직 해당 클래스 내부에서만 접근 가능합니다.
  • protected: 해당 클래스와 이를 상속한 클래스에서만 접근 가능합니다.
class Employee {
  public name: string;
  private salary: number;
  protected department: string;

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

  // public 메서드
  getSalary() {
    return this.salary;
  }
}

const emp = new Employee("Jane", 5000, "Engineering");
console.log(emp.name);  // "Jane"
console.log(emp.salary);  // 오류 발생: private 속성 접근 불가

위 예제에서 **salary** 속성은 **private**로 선언되어 외부에서 접근할 수 없습니다. 반면, **name**은 **public**으로 선언되어 외부에서 접근이 가능합니다. **getSalary** 메서드를 통해 **private** 속성에 접근할 수 있습니다.

3. 상속(Inheritance)

TypeScript의 클래스는 **상속(Inheritance)**을 지원합니다. 이를 통해 부모 클래스의 속성과 메서드를 자식 클래스에서 재사용할 수 있습니다. 자식 클래스는 부모 클래스의 기능을 상속받고, 필요에 따라 **오버라이드**(메서드 재정의)할 수 있습니다.

class Animal {
  name: string;

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

  makeSound() {
    console.log(`${this.name} makes a sound.`);
  }
}

class Dog extends Animal {
  constructor(name: string) {
    super(name);  // 부모 클래스 생성자 호출
  }

  makeSound() {
    console.log(`${this.name} barks.`);
  }
}

const dog = new Dog("Rex");
dog.makeSound();  // "Rex barks."

위 예제에서 **Dog** 클래스는 **Animal** 클래스를 상속받고 있습니다. **super(name)**을 사용하여 부모 클래스의 생성자를 호출하며, **makeSound** 메서드를 오버라이드하여 **Dog** 클래스에서 다른 동작을 수행하도록 합니다. 결과적으로 **Rex**는 "barks"라는 소리를 냅니다.

4. 추상 클래스(Abstraction)

**추상 클래스(abstract class)**는 직접 인스턴스를 생성할 수 없는 클래스로, 다른 클래스가 이를 상속받아 구체적인 구현을 해야 합니다. 추상 클래스는 **추상 메서드**를 포함할 수 있으며, 이 메서드는 자식 클래스에서 반드시 구현해야 합니다.

abstract class Shape {
  abstract area(): number;

  display() {
    console.log("Displaying the shape.");
  }
}

class Circle extends Shape {
  radius: number;

  constructor(radius: number) {
    super();
    this.radius = radius;
  }

  area() {
    return Math.PI * this.radius * this.radius;
  }
}

const circle = new Circle(5);
console.log(circle.area());  // 78.53981633974483

**Shape**는 추상 클래스이고, **area**는 추상 메서드입니다. **Circle** 클래스는 **Shape**를 상속받아 **area** 메서드를 구현해야만 인스턴스를 생성할 수 있습니다. 이를 통해 **추상화**를 구현할 수 있습니다.

TypeScript에서 객체지향 프로그래밍 활용하기

**객체지향 프로그래밍(OOP)**은 코드의 재사용성, 유지보수성, 확장성을 높이는 데 중요한 패러다임입니다. TypeScript에서는 클래스와 객체지향 프로그래밍의 핵심 개념을 활용하여, 더 안정적이고 효율적인 코드를 작성할 수 있습니다. 이번 강의를 통해 TypeScript에서 **클래스**, **상속**, **추상 클래스**, **접근 제어자** 등의 개념을 익히고, 객체지향 프로그래밍을 효과적으로 적용할 수 있기를 바랍니다.

마무리: 객체지향 프로그래밍의 중요성

**객체지향 프로그래밍(OOP)**은 복잡한 시스템을 구조적으로 관리하고, 코드를 효율적으로 확장할 수 있는 매우 중요한 패러다임입니다. TypeScript에서는 클래스를 활용하여 객체지향 프로그래밍을 손쉽게 구현할 수 있으며, 타입 시스템 덕분에 더욱 안전한 코드 작성이 가능합니다. 다음 강의에서는 **TypeScript에서 인터페이스와 제네릭**을 활용하여 더욱 강력한 코드 구조를 만드는 방법을 배워보겠습니다.