요약: 이 글에서는 TypeScript를 사용하여 객체 지향 프로그래밍(Object-Oriented Programming, OOP)을 구현하는 방법을 설명합니다. TypeScript의 클래스, 인터페이스, 접근 제한자, 상속 등의 기능을 활용하여 OOP 원칙을 적용하는 방법을 알아봅시다.
클래스(Class)와 객체(Object)
TypeScript에서 클래스를 정의하고 객체를 생성하는 방법은 다음과 같습니다.
class Dog {
name: string;
constructor(name: string) {
this.name = name;
}
bark(): void {
console.log(`${this.name} says woof!`);
}
}
const myDog = new Dog("Max");
myDog.bark(); // Max says woof!
위 예제에서 Dog 클래스를 정의하고, name 속성과 bark 메소드를 가진 객체 myDog를 생성했습니다.
인터페이스(Interface)
인터페이스는 클래스가 구현해야 하는 메소드와 속성을 정의합니다. 인터페이스를 사용하면 구현체가 정해진 규약을 따르도록 강제할 수 있습니다.
interface Animal {
name: string;
makeSound(): void;
}
class Cat implements Animal {
name: string;
constructor(name: string) {
this.name = name;
}
makeSound(): void {
console.log(`${this.name} says meow!`);
}
}
const myCat = new Cat("Mimi");
myCat.makeSound(); // Mimi says meow!
위 예제에서 Animal 인터페이스를 정의하고, Cat 클래스가 이를 구현하도록 했습니다.
접근 제한자(Access Modifiers)
TypeScript에서는 클래스의 멤버에 접근 제한자를 사용하여 접근을 제한할 수 있습니다. 접근 제한자에는 public, private, 그리고 protected가 있습니다.
- public: 어디서든 접근 가능한 멤버입니다. 기본적으로 모든 멤버는 public입니다.
- private: 오직 해당 클래스 내에서만 접근 가능한 멤버입니다.
- protected: 해당 클래스와 파생된 클래스 내에서 접근 가능한 멤버입니다.
class Animal {
public name: string;
private age: number;
protected isAlive: boolean;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
this.isAlive = true;
}
public makeSound(): void {
console.log(`${this.name} makes a sound.`);
}
}
class Dog extends Animal {
public bark(): void {
console.log(`${this.name} says woof!`);
// console.log(this.age); // Error: Property 'age' is private and only accessible within class 'Animal'.
console.log(this.isAlive); // OK
}
}
위 예제에서 Animal 클래스의 멤버에 접근 제한자를 사용하여 접근 범위를 지정했습니다. Dog 클래스는 Animal 클래스를 상속받아 확장되었습니다.
상속(Inheritance)과 추상 클래스(Abstract Class)
TypeScript에서 상속을 사용하여 기존 클래스를 확장하고 재사용할 수 있습니다. extends 키워드를 사용하여 상속을 구현할 수 있습니다. 추상 클래스는 직접 인스턴스화할 수 없으며, 하위 클래스에서 구현해야 하는 추상 메소드를 포함할 수 있습니다. abstract 키워드를 사용하여 추상 클래스와 추상 메소드를 정의합니다.
abstract class Animal {
constructor(public name: string) {}
abstract makeSound(): void;
}
class Dog extends Animal {
makeSound(): void {
console.log(`${this.name} says woof!`);
}
}
class Cat extends Animal {
makeSound(): void {
console.log(`${this.name} says meow!`);
}
}
const myDog = new Dog("Max");
myDog.makeSound(); // Max says woof!
const myCat = new Cat("Mimi");
myCat.makeSound(); // Mimi says meow!
위 예제에서 Animal 클래스를 추상 클래스로 정의하고, 추상 메소드 makeSound를 선언했습니다. Dog와 Cat 클래스는 Animal 클래스를 상속받아 makeSound 메소드를 구현했습니다.
다형성(Polymorphism)
다형성은 동일한 인터페이스를 구현한 여러 객체가 동일한 메소드를 호출하여 다양한 결과를 얻는 것을 의미합니다.
interface Animal {
makeSound(): void;
}
class Dog implements Animal {
constructor(public name: string) {}
makeSound(): void {
console.log(`${this.name} says woof!`);
}
}
class Cat implements Animal {
constructor(public name: string) {}
makeSound(): void {
console.log(`${this.name} says meow!`);
}
}
function makeAnimalsSpeak(animals: Animal[]): void {
animals.forEach((animal) => animal.makeSound());
}
const myDog = new Dog("Max");
const myCat = new Cat("Mimi");
makeAnimalsSpeak([myDog, myCat]); // Max says woof! Mimi says meow!
위 예제에서 Dog와 Cat 클래스는 동일한 Animal 인터페이스를 구현했습니다. makeAnimalsSpeak 함수는 Animal 인터페이스를 구현한 객체 배열을 인수로 받아, 각 객체의 makeSound 메소드를 호출합니다.
이렇게 TypeScript를 활용하면 객체 지향 프로그래밍의 원칙과 기능을 적용하여 유지 보수가 쉽고, 확장 가능한 코드를 작성할 수 있습니다. 클래스, 인터페이스, 접근 제한자, 상속, 다형성 등의 개념을 이해하고 활용하여 프로젝트의 효율성을 높이세요.
'자기개발 > 검색한 자료 정리' 카테고리의 다른 글
CSS 선택자에 대한 깊이 있는 이해와 활용 (0) | 2023.04.22 |
---|---|
Java 8의 Optional 클래스를 활용한 안전한 null 처리 방법 (0) | 2023.04.22 |
JavaScript의 클로저와 스코프 이해하기 (0) | 2023.04.21 |
Java에서 JUnit과 Mockito를 활용한 단위 테스트 작성 방법 (0) | 2023.04.21 |
React와 TypeScript를 활용한 현대 웹 애플리케이션 개발 (0) | 2023.04.21 |