abstract
abstract
키워드를 사용한 클래스는 추상 클래스라고 하며, 다음과 같은 특징과 목적을 가지고 있습니다.
1. 인스턴스화가 불가능
추상 클래스는 직접 인스턴스화할 수 없습니다. 즉, new
키워드로 객체를 생성할 수 없습니다. 오직 다른 클래스가 이를 상속하고 구체적인 구현을 제공할 때만 인스턴스를 만들 수 있습니다.
abstract class Animal {
abstract makeSound(): void; // 추상 메서드
move(): void {
console.log("Moving...");
}
}
const animal = new Animal(); // 오류 발생: 추상 클래스는 인스턴스화할 수 없습니다.
2. 추상 메서드 포함 가능
추상 클래스는 추상 메서드를 포함할 수 있습니다. 추상 메서드는 선언만 하고 구현하지 않은 메서드입니다. 추상 메서드는 하위 클래스에서 반드시 구현해야 하며, 추상 메서드를 포함하는 클래스는 반드시 abstract
로 선언해야 합니다.
abstract class Animal {
abstract makeSound(): void; // 하위 클래스에서 구현해야 하는 추상 메서드
move(): void {
console.log("Moving...");
}
}
class Dog extends Animal {
makeSound(): void {
console.log("Woof!");
}
}
const dog = new Dog();
dog.makeSound(); // "Woof!"
dog.move(); // "Moving..."
위 예시에서 Dog
클래스는 Animal
클래스를 상속받아 makeSound()
메서드를 구현했습니다.
3. 상속의 기본 틀 제공
추상 클래스는 기본적인 동작이나 메서드를 포함하면서도 구체적인 동작은 하위 클래스에서 구현하도록 하는 기본 틀을 제공합니다. 이를 통해 상속을 사용하는 클래스들 간의 일관성을 보장할 수 있습니다.
abstract class Shape {
abstract getArea(): number;
describe(): void {
console.log("This shape has an area of:", this.getArea());
}
}
class Circle extends Shape {
constructor(private radius: number) {
super();
}
getArea(): number {
return Math.PI * this.radius * this.radius;
}
}
const circle = new Circle(5);
circle.describe(); // This shape has an area of: 78.53981633974483
4. 공통 기능의 정의와 일관성 유지
추상 클래스는 공통 기능을 정의하고, 일관된 인터페이스를 제공하여 여러 하위 클래스들이 동일한 방식으로 동작할 수 있도록 합니다.
요약
- 인스턴스화 불가: 직접적으로 객체 생성이 불가능합니다.
- 추상 메서드 포함 가능: 하위 클래스가 구현해야 할 메서드를 선언할 수 있습니다.
- 기본 틀 제공: 공통 메서드를 제공하고, 하위 클래스에서 구체적인 구현을 강제합니다.
implements
implements
와 extends
는 클래스가 다른 클래스나 인터페이스와 관계를 정의하는 방식에서 중요한 차이점을 가지고 있습니다.
extends
: 클래스 상속
extends
키워드는 클래스를 상속하여 새로운 클래스를 생성할 때 사용됩니다. 이를 통해 기존 클래스의 속성 및 메서드를 가져오면서 추가 기능을 정의하거나 기존 기능을 재정의할 수 있습니다.
- 부모 클래스의 속성과 메서드 상속: 하위 클래스는 부모 클래스의 모든 속성과 메서드를 상속받습니다.
- 상속받은 메서드 재정의 가능: 하위 클래스는 상속받은 메서드를 오버라이딩(재정의)하여 동작을 수정할 수 있습니다.
- 다중 상속 불가: JavaScript와 TypeScript에서는 한 클래스만 상속할 수 있습니다.
예시
class Animal {
move(): void {
console.log("Moving...");
}
}
class Dog extends Animal {
bark(): void {
console.log("Woof!");
}
}
const dog = new Dog();
dog.move(); // "Moving..." (Animal의 메서드)
dog.bark(); // "Woof!" (Dog의 메서드)
여기서 Dog
클래스는 Animal
클래스를 상속받았기 때문에, move
메서드도 사용할 수 있습니다.
implements
: 인터페이스 구현
implements
키워드는 인터페이스의 구조를 구현할 때 사용됩니다. 인터페이스는 메서드와 속성의 구조만 정의하고, 실제 구현은 포함하지 않으며, 클래스에서 이를 구현하도록 강제합니다.
- 구조 강제:
implements
는 클래스가 특정 메서드와 속성을 포함하도록 강제하지만, 실제 구현은 클래스 내에서 정의됩니다. - 다중 구현 가능: 클래스는 여러 인터페이스를 동시에
implements
할 수 있습니다. - 코드 공유 없음: 인터페이스는 구조만 제공하고 실제 코드는 없으므로
extends
와 달리 코드가 공유되지 않습니다.
예시
interface Swimmer {
swim(): void;
}
interface Runner {
run(): void;
}
class Person implements Swimmer, Runner {
swim(): void {
console.log("Swimming...");
}
run(): void {
console.log("Running...");
}
}
const person = new Person();
person.swim(); // "Swimming..."
person.run(); // "Running..."
위 예시에서 Person
클래스는 Swimmer
와 Runner
인터페이스를 구현하여 두 인터페이스에서 정의한 swim
과 run
메서드를 반드시 포함해야 합니다.
요약
기능 | extends |
implements |
---|---|---|
목적 | 클래스 상속을 통해 코드 재사용 | 인터페이스의 구조 강제 |
코드 공유 | 부모 클래스의 코드 사용 가능 | 인터페이스는 구현을 포함하지 않음 |
메서드 재정의 | 메서드를 재정의할 수 있음 | 인터페이스의 구현만 포함 |
다중 사용 | 단일 상속 가능 | 여러 인터페이스 구현 가능 |
따라서, extends
는 클래스 간의 상속을 통해 기능을 재사용하거나 확장할 때 사용하고, implements
는 인터페이스를 통해 클래스가 특정 구조를 갖추도록 할 때 사용합니다.
'TIL' 카테고리의 다른 글
[241203 TIL] gql apolloClient 기본 사용법 (0) | 2024.12.03 |
---|---|
[241115 TIL] as const (0) | 2024.11.15 |
[241113 TIL] 5432 port 사용중일때 (0) | 2024.11.13 |
[241106 TIL] Math.sin, cos, tan (0) | 2024.11.06 |
[241031 TIL] pnpm lock 자꾸 변경될 때 (0) | 2024.10.31 |