6장: 타입스크립트의 클래스와 객체지향 프로그래밍
클래스와 객체지향 프로그래밍의 시작
프로그래밍에서 객체지향(OOP)은 소프트웨어를 실제 세계의 사물처럼 조각내어, 각각의 조각(객체)이 자신만의 데이터와 기능을 가지고 협력하도록 만드는 사고방식입니다. TypeScript는 객체지향 언어의 강력함을 그대로 이어받으면서, 정적 타입 시스템을 통해 예측 가능한 코드와 튼튼한 구조 설계를 가능하게 합니다.
클래스란 무엇인가?
클래스는 현실의 사물이나 개념을 코드로 옮길 때 사용하는 '청사진' 또는 '설계도'입니다. 즉, 공장에서 수많은 자동차를 생산하듯, 클래스를 기반으로 여러 객체(인스턴스)를 만들 수 있습니다. 예를 들어, Person
이라는 클래스를 선언하면, 여기에 이름과 나이 등의 속성, 그리고 인사하기 같은 동작을 정의할 수 있습니다.
class Person {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
sayHello() {
console.log(`안녕하세요! 제 이름은 ${this.name}, 나이는 ${this.age}살입니다.`);
}
}
const me = new Person('민수', 27);
me.sayHello(); // "안녕하세요! 제 이름은 민수, 나이는 27살입니다."
여기서 constructor
는 클래스 인스턴스를 만들 때 초기값을 세팅하는 특별한 함수입니다. this
는 만들어진 객체 자신을 가리킵니다.
객체지향의 기본 원칙
TypeScript의 객체지향 프로그래밍은 네 가지 중심 원칙—캡슐화, 상속, 다형성, 추상화—을 토대로 합니다.
캡슐화: 데이터와 동작을 객체 내부에 숨기고, 필요한 인터페이스만 외부에 제공합니다.
상속: 이미 정의된 클래스를 토대로 새로운 클래스를 만들어, 코드를 재활용하고 기능을 확장할 수 있습니다.
다형성: 같은 이름의 메서드가 다양한 방식으로 동작하도록 허용합니다.
추상화: 공통된 특성만을 뽑아내어 구조를 단순화합니다.
이러한 원칙들은 코드의 유연성과 유지보수를 뛰어나게 만듭니다.
클래스와 인터페이스, 타입의 조화
TypeScript에서는 클래스와 더불어, 인터페이스나 타입 별칭과 잘 조합해 객체의 구조나 역할을 엄격하게 규정할 수 있습니다. 인터페이스를 통해 클래스의 설계를 미리 명세하고, 클래스가 이를 구현(implements)하도록 강제함으로써, 일관성 높은 코드를 유지할 수 있습니다.
클래스 상속과 확장
기존 클래스를 기반으로 더 다양한 기능을 가진 새 클래스를 만들고 싶다면, extends
를 사용해 상속할 수 있습니다.
class Student extends Person {
grade: number;
constructor(name: string, age: number, grade: number) {
super(name, age);
this.grade = grade;
}
study() {
console.log(`${this.name} 학생이 공부를 시작합니다.`);
}
}
const student = new Student('지은', 20, 3);
student.sayHello(); // Person의 기능 이용
student.study(); // Student의 고유 기능
super
는 부모 클래스의 생성자나 메서드를 호출할 때 사용합니다.
캡슐화와 접근 제어자
TypeScript에서는 클래스의 속성이나 메서드에 접근 제한자를 붙여, 외부에서 잘못 사용하는 일을 방지할 수 있습니다. 대표적으로 public
, private
, protected
가 있습니다. private
로 지정하면 클래스 내부에서만 접근할 수 있고, protected
는 상속받은 클래스까지 허용됩니다.
class BankAccount {
private balance: number;
constructor(balance: number) {
this.balance = balance;
}
deposit(amount: number) {
this.balance += amount;
}
getBalance() {
return this.balance;
}
}
객체지향 프로그래밍, 왜 쓰는가?
프로그램이 커질수록 유지보수와 확장이 중요해집니다. 객체지향 접근은 코드를 재사용하고, 역할을 분리하며, 복잡한 문제를 작은 단위로 다룰 수 있게 도와줍니다. TypeScript의 클래스와 객체지향 기능을 익혀두면, 대규모 프로젝트나 협업에도 자신감을 가질 수 있습니다.
이번 장에서 배운 객체지향의 핵심과 클래스 설계 원리는 앞으로의 TypeScript 학습과 실제 프로그래밍에 든든한 토대가 되어줄 것입니다.