Search

추상클래스 vs 인터페이스

추상클래스란?

추상클래스는 말 그대로 추상적으로밖에 그려지지 않은 클래스이다.
즉, 클래스가 전체적인 구성을 다 가지지 못한 채 설계만 되어 있는 클래스이다. 미완성 설계도로는 제품을 만들 수 없듯이 추상클래스로는 인스턴스를 생성할 수 없다.
추상 클래스는 상속(Extends)을 통해서 자식 클래스에 의해 완성이 된다.
그래서 추상클래스는 그 자체로는 제 기능을 다하지 못하지만, 새로운 기능을 정의하는데 있어서 틀이 된다.

추상클래스의 특징

abstract 키워드를 사용하여 정의한다.
인스턴스화 할 수 없고, 상속을 통해서만 사용된다.
추상 메서드는 구현하지 않으며, 하위 클래스에서 반드시 구현해야 한다.
구현된 메서드도 포함될 수 있어, 공통 기능을 정의하고 재사용할 수 있다.
예시
abstract class Animal { constructor(public name: string) {} // 구현이 필요한 추상 메서드 abstract makeSound(): void; // 공통 기능 구현 메서드 move(): void { console.log(`${this.name} is moving.`); } } class Dog extends Animal { makeSound(): void { console.log("Bark"); } } const dog = new Dog("Buddy"); dog.move(); // 출력: Buddy is moving. dog.makeSound(); // 출력: Bark
TypeScript
복사
Animal 추상 클래스는 makeSound()라는 추상 메서드를 정의합니다.
Dog 클래스는 Animal을 상속받아 makeSound()를 구현해야만 합니다.
move() 메서드는 공통 기능으로 구현되어, 상속받은 모든 클래스에서 사용할 수 있습니다.

추상 클래스의 장점

공통된 로직을 상위 클래스에 구현해 코드 중복을 줄일 수 있습니다.
특정 메서드나 속성의 구현을 강제할 수 있어 일관된 구조를 유지할 수 있습니다.

인터페이스란?

인터페이스는 클래스나 객체가 가져야 하는 형태와 구조를 정의하는 용도로 사용됩니다. 인터페이스는 순수하게 타입 정의만을 목적으로 하며, 실제 구현은 포함하지 않습니다.

인터페이스의 특징

interface 키워드를 사용하여 정의합니다.
메서드의 구현을 포함하지 않으며, 형태만 정의합니다.
여러 인터페이스를 동시에 구현할 수 있습니다 (다중 구현 지원).
클래스뿐만 아니라, 객체 리터럴의 구조를 정의할 때도 사용됩니다.

인터페이스 예시

typescript 코드 복사 interface Animal { name: string; makeSound(): void; } class Cat implements Animal { name: string; constructor(name: string) { this.name = name; } makeSound(): void { console.log("Meow"); } } const cat = new Cat("Whiskers"); cat.makeSound(); // 출력: Meow
TypeScript
복사
Animal 인터페이스는 name 속성과 makeSound() 메서드를 요구합니다.
Cat 클래스는 Animal 인터페이스를 **구현(implements)**하여, 인터페이스에서 정의된 구조를 따릅니다.

인터페이스의 장점

특정 구조를 요구함으로써 타입 안전성을 높이고 일관성을 유지할 수 있습니다.
인터페이스를 통해 객체의 구조를 유연하게 정의할 수 있으며, 다중 구현이 가능하여 여러 인터페이스를 조합하여 사용할 수 있습니다.

3. 추상 클래스와 인터페이스의 차이점

비교 항목
추상 클래스
인터페이스
키워드
abstract class
interface
목적
클래스의 공통 기능 제공 및 일부 구현 강제
타입 체크 및 구조 정의
인스턴스화
직접 인스턴스화할 수 없음
구현체가 없어 인스턴스화할 수 없음
메서드 구현
구현된 메서드와 추상 메서드 둘 다 포함 가능
메서드 구현 불가능, 형태만 정의
다중 상속
다중 상속 불가 (단일 상속)
다중 구현 가능
사용 대상
클래스에만 사용 가능
클래스 및 객체 리터럴에도 사용 가능

4. 추상 클래스와 인터페이스의 혼합 사용

TypeScript에서는 추상 클래스와 인터페이스를 혼합하여 사용하여 상속과 타입 정의를 동시에 구현할 수 있습니다.

예시: 추상 클래스와 인터페이스 혼합 사용

typescript 코드 복사 interface SoundMaker { makeSound(): void; } abstract class Animal implements SoundMaker { constructor(public name: string) {} abstract makeSound(): void; move(): void { console.log(`${this.name} is moving.`); } } class Bird extends Animal { makeSound(): void { console.log("Chirp"); } } const bird = new Bird("Tweety"); bird.move(); // 출력: Tweety is moving. bird.makeSound(); // 출력: Chirp
TypeScript
복사
SoundMaker 인터페이스는 makeSound() 메서드를 요구합니다.
Animal 추상 클래스는 SoundMaker 인터페이스를 구현하며, 일부 메서드는 구체적인 구현 없이 추상 메서드로 남겨 하위 클래스에서 구현을 강제합니다.
Bird 클래스는 Animal을 상속받아 makeSound()를 구현합니다.

5. 추상 클래스와 인터페이스 사용 시 고려 사항

공통된 기능이 필요한 경우: 여러 클래스에 공통된 기능이 필요하다면 추상 클래스를 사용하여 기본적인 구현을 상속받게 합니다.
구조와 타입만 필요할 경우: 특정 구조를 강제하고자 할 때는 인터페이스를 사용하여 타입을 정의합니다.
다중 구현이 필요할 때: 여러 인터페이스를 동시에 구현할 수 있지만, 클래스는 한 번에 하나의 클래스만 상속할 수 있습니다. 다중 구현이 필요하면 인터페이스를 사용합니다.

요약

추상 클래스는 공통된 기능을 제공하고 일부 구현을 강제할 때 유용하며, 단일 상속만 가능합니다.
인터페이스는 클래스 및 객체 리터럴의 구조를 정의하는 데 사용되며, 다중 구현이 가능하여 유연한 타입 정의가 가능합니다.
두 가지는 필요에 따라 혼합하여 상속과 타입 체크를 동시에 구현할 수 있습니다.