클래스 기본 문법
자바스크립트는 프로토타입 기반 객체 지향 언어이지만, ES2015(ES6)부터는 다른 객체 지향 언어와 유사한 클래스(Class) 문법을 제공하기 시작했습니다. 클래스는 객체 지향 프로그래밍의 핵심 개념인 추상화, 캡슐화, 상속, 다형성을 구현하는 데 사용되는 문법적 설탕(Syntactic Sugar)입니다. 타입스크립트는 이 자바스크립트의 클래스 문법에 강력한 타입 시스템을 더하여 클래스를 더욱 안전하고 견고하게 만들 수 있도록 돕습니다.
이번 절에서는 타입스크립트의 클래스 기본 문법과 핵심 요소들을 상세히 살펴보겠습니다.
클래스 선언과 인스턴스 생성
클래스를 선언하는 것은 class
키워드를 사용하며, 일반적으로 클래스 이름은 파스칼 케이스(PascalCase, 첫 글자 대문자)를 사용합니다.
// 'Person'이라는 이름의 클래스를 선언합니다.
class Person {
// 1. 속성 (Property): 클래스의 데이터를 나타냅니다.
// 각 속성에도 타입을 명시합니다.
name: string;
age: number;
private _job: string; // private 접근 제어자를 가진 속성
// 2. 생성자 (Constructor): 클래스의 인스턴스가 생성될 때 호출됩니다.
// 인스턴스의 속성들을 초기화하는 역할을 합니다.
constructor(name: string, age: number, job: string) {
this.name = name; // this는 현재 생성되는 인스턴스를 가리킵니다.
this.age = age;
this._job = job;
}
// 3. 메서드 (Method): 클래스의 동작(함수)을 나타냅니다.
// 매개변수와 반환 값에 타입을 명시합니다.
greet(): string {
return `안녕하세요, ${this.name}입니다. 저는 ${this.age}살이고 ${this._job}입니다.`;
}
// Getter (속성 값을 읽을 때 사용)
get job(): string {
return this._job;
}
// Setter (속성 값을 설정할 때 사용)
set job(newJob: string) {
if (newJob.length < 2) {
console.log("직업명은 2글자 이상이어야 합니다.");
return;
}
this._job = newJob;
}
}
// 클래스의 인스턴스 (객체) 생성
// new 키워드와 함께 생성자를 호출합니다.
const person1 = new Person("김철수", 30, "개발자");
const person2 = new Person("이영희", 25, "디자이너");
console.log(person1.name); // 김철수
console.log(person1.age); // 30
console.log(person1.greet()); // 안녕하세요, 김철수입니다. 저는 30살이고 개발자입니다.
// Getter 사용
console.log(person2.job); // 디자이너
// Setter 사용
person2.job = "마케터";
console.log(person2.greet()); // 안녕하세요, 이영희입니다. 저는 25살이고 마케터입니다.
person2.job = "SE"; // setter에 정의된 조건에 의해 변경되지 않음
console.log(person2.job); // 마케터 (변경되지 않음)
클래스의 기본적인 구성 요소는 다음과 같습니다.
- 속성 (Properties): 클래스의 상태를 나타내는 변수입니다. 각 속성에도 타입을 명시합니다. (예:
name: string;
) - 생성자 (Constructor):
new
키워드를 통해 클래스의 인스턴스를 생성할 때 호출되는 특별한 메서드입니다. 인스턴스의 초기 상태를 설정하는 역할을 합니다. - 메서드 (Methods): 클래스가 수행할 수 있는 동작을 나타내는 함수입니다. 일반 함수와 마찬가지로 매개변수와 반환 값에 타입을 명시할 수 있습니다.
this
키워드: 클래스 내부에서this
는 현재 클래스의 인스턴스를 가리킵니다. 이를 통해 인스턴스의 속성과 메서드에 접근할 수 있습니다.- Getter/Setter: 특정 속성에 대한 읽기/쓰기 접근을 제어하는 메서드입니다. 속성처럼 접근하지만 내부적으로는 함수가 실행됩니다.
접근 제어자
타입스크립트의 클래스는 속성과 메서드의 접근 수준을 제어하는 세 가지 접근 제어자(Access Modifiers) 를 제공합니다. 이는 객체 지향의 캡슐화(Encapsulation) 를 구현하는 데 중요한 역할을 합니다.
public
(공개):
가장 기본적인 접근 제어자입니다. 선언된 속성이나 메서드가 클래스 외부에서 자유롭게 접근 가능함을 의미합니다. 아무런 접근 제어자를 명시하지 않으면 기본적으로 public
으로 간주됩니다.
class PublicExample {
public value: number; // public 명시
message: string; // 기본값 public
constructor(val: number, msg: string) {
this.value = val;
this.message = msg;
}
public display(): void {
console.log(`Value: ${this.value}, Message: ${this.message}`);
}
}
const pe = new PublicExample(10, "Hello");
console.log(pe.value); // 10 (접근 가능)
pe.display(); // Display: Value: 10, Message: Hello (접근 가능)
private
(비공개):
선언된 속성이나 메서드가 해당 클래스 내부에서만 접근 가능함을 의미합니다. 클래스 외부나 상속받은 자식 클래스에서도 접근할 수 없습니다. 이는 특정 데이터를 외부에서 직접 변경하지 못하도록 보호할 때 유용합니다.
class PrivateExample {
private secretCode: string; // private 속성
constructor(code: string) {
this.secretCode = code;
}
public revealCode(): string {
return `비밀 코드: ${this.secretCode}`; // 클래스 내부에서 접근 가능
}
}
const pve = new PrivateExample("MY_PRIVATE_KEY");
// console.log(pve.secretCode); // Error: Property 'secretCode' is private and only accessible within class 'PrivateExample'.
console.log(pve.revealCode()); // 비밀 코드: MY_PRIVATE_KEY (public 메서드를 통해 간접 접근)
자바스크립트의 #
프라이빗 필드 문법과 유사하나, 타입스크립트의 private
는 컴파일 시점에 검사되는 타입 시스템 레벨의 제약입니다.
protected
(보호된):
선언된 속성이나 메서드가 해당 클래스 내부와 이 클래스를 상속받은 자식 클래스 내부에서만 접근 가능함을 의미합니다. 클래스 외부에서는 접근할 수 없습니다. 이는 부모 클래스의 특정 속성이나 메서드를 자식 클래스에서 활용해야 하지만, 외부 노출은 막고 싶을 때 사용됩니다.
class ProtectedExample {
protected protectedValue: string; // protected 속성
constructor(value: string) {
this.protectedValue = value;
}
protected getProtectedValue(): string {
return this.protectedValue;
}
}
class ChildExample extends ProtectedExample {
constructor(value: string) {
super(value); // 부모 클래스의 생성자 호출
}
public printProtected(): void {
console.log(`자식에서 접근: ${this.protectedValue}`); // 자식 클래스에서 접근 가능
console.log(`자식에서 메서드 접근: ${this.getProtectedValue()}`); // 자식 클래스에서 메서드 접근 가능
}
}
const child = new ChildExample("보호된 값");
child.printProtected(); // 자식에서 접근: 보호된 값, 자식에서 메서드 접근: 보호된 값
// console.log(child.protectedValue); // Error: Property 'protectedValue' is protected and only accessible within class 'ProtectedExample' and its subclasses.
생성자의 매개변수에 접근 제어자 사용하기
타입스크립트에서는 생성자의 매개변수에 직접 접근 제어자(public
, private
, protected
, readonly
)를 붙여서, 해당 매개변수를 클래스의 속성으로 동시에 선언하고 초기화할 수 있는 편리한 문법을 제공합니다.
class CompactPerson {
// 매개변수에 public을 붙여 자동으로 속성으로 선언하고 초기화
constructor(public name: string, public age: number, private _secretInfo: string) {
// this.name = name; 이런 식으로 속성 할당 코드를 생략할 수 있습니다.
}
get secretInfo(): string {
return this._secretInfo;
}
}
const compactP = new CompactPerson("김효진", 28, "비밀 일기");
console.log(compactP.name); // 김효진
console.log(compactP.age); // 28
// console.log(compactP._secretInfo); // Error: private 속성이므로 접근 불가
console.log(compactP.secretInfo); // 비밀 일기 (getter를 통해 접근)
이 방식은 코드를 훨씬 간결하게 만들어주며, 특히 클래스 속성 정의와 생성자 초기화 코드를 줄이는 데 효과적입니다.
static
속성과 메서드
클래스의 static
(정적) 멤버는 클래스의 인스턴스가 아닌, 클래스 자체에 속하는 속성이나 메서드입니다. 즉, new
키워드로 인스턴스를 생성하지 않고도 클래스 이름으로 직접 접근할 수 있습니다. 유틸리티 함수나 모든 인스턴스가 공유해야 하는 상수 값 등을 정의할 때 유용합니다.
class MathUtil {
static PI: number = 3.14159; // 정적 속성
static calculateCircleArea(radius: number): number { // 정적 메서드
return this.PI * radius * radius; // 정적 메서드 내에서 정적 속성 접근 시 this.PI
}
// 인스턴스 메서드에서는 정적 멤버에 직접 접근하지 않는 것이 일반적입니다.
// 다만 클래스 이름으로 접근은 가능합니다.
public getInstancePi(): number {
return MathUtil.PI; // 클래스 이름으로 접근
}
}
// 인스턴스 생성 없이 직접 클래스 이름으로 접근
console.log(MathUtil.PI); // 3.14159
console.log(MathUtil.calculateCircleArea(5)); // 78.53975
const util = new MathUtil();
console.log(util.getInstancePi()); // 3.14159 (인스턴스를 통해 정적 속성 접근)
// 오류: 인스턴스를 통해 정적 메서드에 접근할 수 없습니다.
// util.calculateCircleArea(10); // Error: Property 'calculateCircleArea' does not exist on type 'MathUtil'. Did you mean 'static calculateCircleArea'?
static
멤버는 클래스명 뒤에 점(.
)을 찍어 접근합니다. this
를 사용하면 같은 클래스 내의 다른 static
멤버에 접근할 수 있습니다.
클래스는 복잡한 애플리케이션의 구조를 체계적으로 설계하고 관리하는 데 필수적인 요소입니다. 타입스크립트는 자바스크립트의 클래스 문법에 타입 안전성과 접근 제어자 같은 객체 지향적 기능을 추가하여, 더욱 견고하고 유지보수하기 쉬운 코드를 작성할 수 있도록 돕습니다.