TypeScript / / 2024. 10. 29. 17:30

TypeScript 인터페이스로 구현하는 클래스

1. 인터페이스의 역할

인터페이스는 타입스크립트에서 클래스의 설계도 역할을 합니다. 인터페이스는 클래스가 가져야 할 **속성(필드)**과 메서드를 정의하여 클래스가 이 규칙을 따르게 합니다. 이렇게 하면 코드의 일관성을 유지하고, 클래스들이 특정 구조를 준수하도록 강제할 수 있습니다.

2. 인터페이스와 클래스의 관계

타입스크립트에서 클래스가 인터페이스를 "구현"하는 것을 implements 키워드를 사용해 표현합니다. **implements**는 클래스가 해당 인터페이스에서 정의된 모든 속성과 메서드를 구현해야 한다는 의미입니다. 만약 클래스가 인터페이스에서 정의한 내용들을 구현하지 않으면, 컴파일 시 오류가 발생합니다. 이렇게 강제함으로써 타입 안정성을 보장할 수 있습니다.

예제를 통해 더 자세히 보겠습니다.

예제: 인터페이스와 클래스를 활용한 구현

interface CharacterInterface {
  name: string;          // 캐릭터의 이름 (문자열)
  moveSpeed: number;     // 이동 속도 (숫자)
  move(): void;          // 이동 동작을 정의한 메서드 (반환값 없음)
}

class Character implements CharacterInterface {
  // 생성자에서 public, private 키워드로 필드 정의 및 초기화
  constructor(
    public name: string,        // public: 외부에서 접근 가능
    public moveSpeed: number,   // public: 외부에서 접근 가능
    private extra: string       // private: 클래스 내부에서만 접근 가능
  ) {}

  // 인터페이스에 정의된 move 메서드를 구현
  move(): void {
    console.log(`${this.moveSpeed} 속도로 이동!`);
  }
}

const character = new Character("Warrior", 10, "ExtraPower");
character.move(); // 출력: 10 속도로 이동!

 

위 예제에서 살펴보면 다음과 같은 구조가 있습니다.

1. 인터페이스 정의 (CharacterInterface)

interface CharacterInterface {
  name: string;
  moveSpeed: number;
  move(): void;
}
  • 이 인터페이스는 name과 moveSpeed라는 필드 move()라는 메서드를 갖고 있습니다.
  • 인터페이스는 구체적인 구현을 갖지 않으며, 필드와 메서드의 구조만 정의합니다.
  • 다른 클래스나 객체가 이 구조를 따르도록 강제합니다.

2. 클래스 구현 (Character)

class Character implements CharacterInterface {
  constructor(
    public name: string,
    public moveSpeed: number,
    private extra: string
  ) {}
  
  move(): void {
    console.log(`${this.moveSpeed} 속도로 이동!`);
  }
}
  • implements CharacterInterface: 이 부분은 Character 클래스가 인터페이스를 구현하겠다는 선언입니다. 이를 통해 Character 클래스는 인터페이스에서 정의된 모든 필드와 메서드를 가져야 합니다.
  • 필드와 생성자:
    • public name: name 필드는 public 접근 제어자가 붙어서 외부에서 자유롭게 접근할 수 있습니다. 인터페이스에서 정의된 name: string을 충족합니다.
    • public moveSpeed: moveSpeed도 인터페이스의 moveSpeed: number를 만족하며, 외부에서 접근 가능합니다.
    • private extra: extra는 인터페이스에 포함되지 않았지만 클래스 자체에서 추가한 필드입니다. private로 선언되어 클래스 외부에서는 접근할 수 없습니다.
  • move() 메서드:
    • 인터페이스에서 정의된 move(): void 메서드를 구현합니다.
    • console.log를 통해 이동 속도를 출력합니다.
    • 이렇게 인터페이스에서 요구하는 모든 필드와 메서드를 충족하지 않으면, 타입스크립트는 컴파일 오류를 발생시킵니다.

3. 구현된 클래스 사용

const character = new Character("Warrior", 10, "ExtraPower");
character.move(); // 출력: 10 속도로 이동!
  • new Character()를 통해 인스턴스를 생성합니다.
  • name과 moveSpeed는 인터페이스에 정의된 필드이므로 클래스 외부에서 접근 가능합니다.
  • **character.move()**를 호출하면 "10 속도로 이동!"이라는 문자열을 출력합니다.

3. 인터페이스를 사용해야 하는 이유

인터페이스를 이용하면 다음과 같은 장점이 있습니다.

  1. 타입 안전성: 클래스가 특정 형식을 반드시 따라야 하므로, 코드의 일관성을 보장하고 컴파일 시점에 오류를 미리 잡아낼 수 있습니다.
  2. 유연한 설계: 인터페이스는 다양한 클래스가 특정 구조를 구현하도록 유도할 수 있습니다. 예를 들어, 여러 개의 캐릭터 클래스(Mage, Archer 등)가 CharacterInterface를 구현하면, 각 캐릭터는 서로 다른 구현을 가질 수 있지만, 일관된 형태의 필드와 메서드를 가집니다.
  3. 다형성: 인터페이스를 타입으로 사용하면 다형성을 활용할 수 있습니다. 예를 들어, 어떤 함수가 CharacterInterface를 요구할 때, 해당 인터페이스를 구현하는 모든 클래스의 인스턴스를 그 함수의 인자로 전달할 수 있습니다.

예제: 인터페이스를 이용한 다형성

function moveCharacter(character: CharacterInterface) {
  character.move();
}

const mage = new Character("Mage", 8, "MagicStaff");
moveCharacter(mage); // 출력: 8 속도로 이동!
  • 함수 moveCharacter는 CharacterInterface를 요구합니다.
  • 이 인터페이스를 구현하는 Character 클래스의 인스턴스인 mage를 전달하여, 다형성을 통해 여러 타입의 객체를 유연하게 처리할 수 있습니다.

정리

  • 인터페이스는 클래스의 설계도를 제공합니다.
  • 클래스가 인터페이스를 **implements**로 구현하면, 인터페이스에서 정의된 모든 필드와 메서드를 강제로 구현해야 합니다.
  • 이를 통해 일관된 구조를 가지며, 컴파일 시점에 타입 오류를 방지할 수 있습니다.
  • 인터페이스를 사용하면 코드의 유연성과 유지보수성이 향상되며, 다양한 클래스들이 같은 인터페이스를 구현하여 다형성을 활용할 수 있습니다.

타입스크립트에서 인터페이스를 사용하여 클래스의 구현을 명확하게 정의하고, 구조적 일관성을 강제하는 것이 큰 장점입니다. 인터페이스와 클래스를 잘 활용하면 안전하고 유지보수하기 쉬운 코드를 작성할 수 있습니다.

'TypeScript' 카테고리의 다른 글

TypeScript 제네릭2  (0) 2024.10.29
TypeScript 제네릭1  (1) 2024.10.29
TypeScript 클래스  (1) 2024.10.29
JavaScript this정리  (0) 2024.10.29
자바스크립트, 타입스크립트 스코프,호이스팅  (2) 2024.10.29
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유