Skip to content

클래스 (Class)

  • 클래스는 객체를 생성하기 위한 하나의 청사진/템플릿 역할을 한다.
  • ES6에서 도입된 문법이며, 생성자(constructor), 속성(properties), 메서드(methods)로 구성된다.
  • TypeScript에서는 클래스 내부의 속성과 매개변수, 반환값 등에 명시적인 타입 지정이 가능하다.

1. 기본 문법

ts
// 클래스 선언
class Country {
  name: string;
  capital: string;
}

// 인스턴스 생성
let country = new Country();

// 인스턴스에 속성 값 직접 할당
country.name = "South Korea";
country.capital = "Seoul";

console.log(country); // Country { name: "South Korea", capital: "Seoul" }
ts
// 생성자(constructor) 활용
class Country {
  name: string;
  capital: string;

  constructor(name: string, capital: string) {
    // 생성자 내부에서 초기화
    this.name = name;
    this.capital = capital;
  }
}

// 인스턴스 생성 시 값 전달
let country = new Country("South Korea", "Seoul");

console.log(country); // Country { name: "South Korea", capital: "Seoul" }
  • 생성자(constructor) 를 활용하면 인스턴스 초기값을 한 번에 설정할 수 있다.
  • 일일이 프로퍼티를 대입하지 않아도 되므로 코드가 간결해진다.

2. 클래스의 상속 (Inheritance)

extends 키워드를 사용하면 부모 클래스의 속성과 메서드를 상속 및 확장할 수 있다.
super()는 부모 클래스의 생성자를 호출한다.

ts
// 부모 클래스
class Continent {
  continentName: string;

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

  getContinentName() {
    return this.continentName;
  }
}

// 자식 클래스
class Country extends Continent {
  name: string;
  capital: string;

  constructor(continentName: string, name: string, capital: string) {
    super(continentName); // 부모 생성자 호출
    this.name = name;
    this.capital = capital;
  }

  // 메서드 오버라이드
  getInfo() {
    return `${this.name}, ${this.capital}, ${this.getContinentName()}`;
  }
}

// 인스턴스 생성
const country = new Country("Asia", "South Korea", "Seoul");
console.log(country.getInfo()); // South Korea, Seoul, Asia
  • 상속의 장점: 중복 코드 최소화, 구조적 확장, 공통 로직 재사용에 유리하다.

3. 접근 제어자 (Access Modifiers)

제어자설명접근 가능 범위
public어디서나 접근 가능 (기본값)클래스 내부, 외부
private / #해당 클래스 내부에서만 접근 가능클래스 내부
protected해당 클래스 및 하위 클래스에서 접근 가능내부 + 하위 클래스

ts
// 접근 제어자 예제
class Continent {
  public continentName: string; // 어디서나 접근 가능
  private population: number; // 클래스 내부에서만 접근 가능

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

  // 내부에서 private 속성 접근 가능
  getPopulation() {
    return this.population;
  }
}

class Country extends Continent {
  name: string;
  capital: string;

  constructor(
    continentName: string,
    population: number,
    name: string,
    capital: string
  ) {
    super(continentName, population);
    this.name = name;
    this.capital = capital;
  }

  getInfo() {
    // private 속성은 접근 불가
    // this.population;
    return `${this.name}, ${this.capital}, ${this.continentName}`;
  }
}

// 인스턴스 생성
const country = new Country("Asia", 4600000000, "South Korea", "Seoul");

console.log(country.getInfo()); // 접근 가능
console.log(country.getPopulation()); // 내부 메서드 통해 간접 접근
// console.log(country.population); Error

💡 TypeScript의 접근 제어자는 컴파일 타임에만 검사되며,

실제 JavaScript 런타임에서는 완전한 캡슐화가 되지 않는다. 런타임 레벨의 캡슐화를 원한다면 #(private field) 사용 권장.


4. 인터페이스 구현 (Implements)

implements 키워드를 사용하면 클래스가 특정 구조(인터페이스) 를 반드시 구현하도록 강제할 수 있다.

ts
// 대륙 인터페이스 정의
interface ContinentInterface {
  getContinentName(): string;
}

// 인터페이스 구현 클래스
class Continent implements ContinentInterface {
  protected continentName: string;

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

  getContinentName() {
    return this.continentName;
  }
}

// 국가 인터페이스 정의
interface CountryInterface {
  capital: string;
  getInfo(): string;
}

// 다중 상속 + 인터페이스 구현
class Country extends Continent implements CountryInterface {
  #name: string; // private 필드
  capital: string;

  constructor(continentName: string, name: string, capital: string) {
    super(continentName);
    this.#name = name;
    this.capital = capital;
  }

  getInfo() {
    return `${this.#name}, ${this.capital}, ${this.getContinentName()}`;
  }
}

const country = new Country("Asia", "South Korea", "Seoul");
console.log(country.getInfo()); // South Korea, Seoul, Asia
  • 인터페이스를 통해 클래스의 일관된 구조를 유지할 수 있다.
    다수의 클래스가 동일한 메서드 시그니처를 가질 수 있도록 강제한다.

5. 추상 클래스 (Abstract Class)

abstract 키워드를 사용해 선언된 클래스는 인스턴스화할 수 없고, 상속을 통해서만 사용 가능하다.

ts
// 추상 클래스 정의
abstract class AbstractCountry {
  name: string;
  capital: string;

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

  setup(): void {
    console.log("setup complete");
  }

  // 추상 메서드
  abstract displayInfo(): void;
}

// const myCountry = new AbstractCountry();
// Error: 추상 클래스는 인스턴스화 불가

// 하위 클래스에서 추상 메서드 구현
class MyCountry extends AbstractCountry {
  displayInfo() {
    console.log(`${this.name}, ${this.capital}`);
  }
}

// 인스턴스 생성
const myCountry = new MyCountry("Germany", "Berlin");
myCountry.setup(); // setup complete
myCountry.displayInfo(); // Germany, Berlin
  • 추상 클래스는 인스턴스를 만들 수 없다.
  • 추상 클래스는 extends 키워드를 사용해 상속받는다.
  • abstract 추상 메서드는 반드시 하위 클래스에서 구체적으로 구현해야 한다.

정리

개념키워드설명
클래스class객체 생성 템플릿
생성자constructor인스턴스 초기화 메서드
상속extends, super부모 클래스 기능 재사용
접근 제어자public, private, protected접근 범위 제한
인터페이스 구현implements클래스가 따라야 할 구조 정의
추상 클래스abstract인스턴스 불가, 상속용 기본 설계