추상클래스란?
추상클래스는 말 그대로 추상적으로밖에 그려지지 않은 클래스이다.
즉, 클래스가 전체적인 구성을 다 가지지 못한 채 설계만 되어 있는 클래스이다. 미완성 설계도로는 제품을 만들 수 없듯이
추상클래스로는 인스턴스를 생성할 수 없다.
추상 클래스는 상속(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. 추상 클래스와 인터페이스 사용 시 고려 사항
•
공통된 기능이 필요한 경우: 여러 클래스에 공통된 기능이 필요하다면 추상 클래스를 사용하여 기본적인 구현을 상속받게 합니다.
•
구조와 타입만 필요할 경우: 특정 구조를 강제하고자 할 때는 인터페이스를 사용하여 타입을 정의합니다.
•
다중 구현이 필요할 때: 여러 인터페이스를 동시에 구현할 수 있지만, 클래스는 한 번에 하나의 클래스만 상속할 수 있습니다. 다중 구현이 필요하면 인터페이스를 사용합니다.
요약
•
추상 클래스는 공통된 기능을 제공하고 일부 구현을 강제할 때 유용하며, 단일 상속만 가능합니다.
•
인터페이스는 클래스 및 객체 리터럴의 구조를 정의하는 데 사용되며, 다중 구현이 가능하여 유연한 타입 정의가 가능합니다.
•
두 가지는 필요에 따라 혼합하여 상속과 타입 체크를 동시에 구현할 수 있습니다.