728x90
728x90
클래스(Class)
들어가며
- 타입스크립트(TypeScript)에서 사용할 수 있는 클래스(Class)에 대해 정리해본다.

클래스(Class)
개념
- 객체(Object)를 생성하기 위한 설계도(Blueprint)
- 데이터를 캡슐화하고, 그 데이터를 조작하는 메서드를 포함하여 객체 지향 프로그래밍(OOP, Object Oriented Programming) 패턴을 따른다.
- 상속(Inheritance)를 지원하며, 복잡한 데이터 구조를 쉽게 생성할 수 있다.
클래스와 생성자(Contructor)
- 클래스에서 생성자(Constructor)는 새 인스턴스를 생성할 때 호출되는 특별한 메서드이다.
- 생성자는 보통 객체의 초기 상태를 설정하는 데 사용된다.
class Book {
// 클래스 속성 선언
title: string;
author: string;
// 생성자
constructor(title: string, author: string) {
this.title = title;
this.author = author;
}
}
const deepWork = new Book('Deep Work', 'Cal Newport');
생성자 생성과 동시에 클래스 속성 선언하기
- 참고로 타입스크립트에서는 @title: string; author: string;@과 같은 클래스 속성 선언이 필요하다.
- 하지만, 생성자 파라미터에 접근자를 추가하면, 클래스 속성을 따로 선언하지 않아도 된다.
class Book {
// 생성자 파라미터에 접근자 추가 -> 따로 클래스 속성을 선언한지 않아도 된다.
constructor(public title: string, public author: string) {}
}
const deepWork = new Book('Deep Work', 'Cal Newport');
인스턴스 속성과 기본값
- 클래스 내에서 정의된 속성들은 인스턴스 속성(Instance Property)이라고 불리며, 클래스의 각 인스턴스에 대해 고유한 값을 가질 수 있다.
- 특정 속성은 생성자에서 초기화되지 않으면 기본값(Default Value)을 가질 수도 있다.
class Book {
title: string;
author: string;
checkedOut: boolean = false; // 기본값 설정
constructor(title: string, author: string) {
this.title = title;
this.author = author;
}
}
const deepWork = new Book('Deep Work', 'Cal Newport');
deepWork.checkedOut = true; // 인스턴스에서 값 변경하기
⇒ @checkedOut@ 속성은 기본적으로 @false@로 설정되지만, 인스턴스에서 값을 변경할 수 있다.
읽기전용(Readonly) 수정자
- @readonly@ 키워드는 해당 속성을 읽기 전용(Readonly)으로 만들어준다.
- 한 번 설정된 이후에는 해당 속성의 값을 변경할 수 없다.
class Book {
readonly title: string; // 읽기전용 설정
author: string;
constructor(title: string, author: string) {
this.title = title;
this.author = author;
}
}
const deepWork = new Book('Deep Work', 'Cal Newport');
deepWork.title = 'Something else'; // 오류 발생
접근 제한자(Access Modifier) : private, public, protected
- 클래스 내에서 @public@과 @private@, @protected@ 접근 제한자(Access Modifier)를 사용하여 속성 및 메서드의 접근 범위를 제어할 수 있다.
- @public@은 어디서든 접근 가능하며, @private@은 클래스 내부에서만 접근할 수 있다. 또한 @protected@는 클래스 내부 및 서브 클래스에서만 접근 가능하다.
class Book {
public readonly title: string;
public author: string;
protected checkedOut: boolean = false; // protected
private dueDate: Date | null = null; // private
constructor(title: string, author: string) {
this.title = title;
this.author = author;
}
public checkOut() {
this.checkedOut = this.toggleCheckedOutStatus();
this.setDueDate();
}
public isCheckedOut() {
return this.checkedOut;
}
protected toggleCheckedOutStatus() {
return !this.checkedOut;
}
private setDueDate() {
const currentDate = new Date();
const dueDate = new Date(currentDate.setDate(currentDate.getDate() + 14));
this.dueDate = dueDate;
}
public getDueDate() {
return this.dueDate;
}
}
// 서브 클래스
class LibraryBook extends Book {
public libraryId: string;
private fineAmount: number = 0; // private
constructor(title: string, author: string, libraryId: string) {
super(title, author);
this.libraryId = libraryId;
}
public checkLibraryStatus() {
// protected 속성 접근
return this.checkedOut ? 'Checked out' : 'Available';
}
public forceCheckOut() {
this.checkedOut = true; // protected 속성 접근
}
private calculateFine() {
if (this.isCheckedOut()) {
this.fineAmount += 10;
}
}
public getFineAmount() {
this.calculateFine();
return this.fineAmount;
}
}
const deepWork = new LibraryBook('Deep Work', 'Cal Newport', 'LB123');
deepWork.forceCheckOut();
console.log(deepWork.checkLibraryStatus()); // 'Checked out'
console.log(deepWork.isCheckedOut()); // true
console.log(deepWork.getDueDate()); // 2주 후의 날짜 출력
console.log(deepWork.getFineAmount()); // 벌금 조회
// console.log(deepWork.fineAmount); // 오류 발생 (fineAmount는 private 속성이므로 외부에서 접근 불가)
접근 제한자(Access Modifier)
| 접근 제한자 | 설명 | 접근 가능 |
| @public@ | - 접근 제한자를 명시하지 않으면 @public@으로 간주된다. (기본값) | 어디서든 접근 가능 (클래스 내부/외부, 서브 클래스) |
| @private@ | - 클래스 외부나 서브 클래스에서 해당 속성이나 메서드에 접근하면 오류가 발생한다. - 클래스 외부에서 해당 속성이나 메서드에 접근을 막아, 데이터 보호 및 캡슐화를 강화한다. |
클래스 내부에서만 접근 가능 |
| @protected@ | - 상속 관계에서만 해당 속성이나 메서드를 활용할 수 있도록 하고, 외부 접근은 차단한다. - @private@과 유사하지만, 서브 클래스에서는 접근이 가능하다. *서브 클래스 : 해당 클래스를 상속 받은 클래스 |
클래스 내부 및 서브 클래스에서만 접근 가능 |
- @public@ 접근 제한자 사용 예
class Book {
public title: string; // 명시적으로 public 선언
author: string; // 접근 제한자를 생략하면 기본적으로 public
constructor(title: string, author: string) {
this.title = title;
this.author = author;
}
}
const book = new Book('Deep Work', 'Cal Newport');
console.log(book.title); // 접근 가능
console.log(book.author); // 접근 가능
- @private@ 접근 제한자 사용 예
class Book {
private checkedOut: boolean = false; // 클래스 내부에서만 접근 가능
constructor(public title: string, public author: string) {}
public checkOut() {
this.checkedOut = true;
}
public isCheckedOut() {
return this.checkedOut;
}
}
const book = new Book('Deep Work', 'Cal Newport');
book.checkOut();
console.log(book.isCheckedOut()); // true
// console.log(book.checkedOut); // 오류 발생 (private 속성은 클래스 외부에서 접근 불가)
- @protected@ 접근 사용자 사용 예
class Book {
protected checkedOut: boolean = false; // 서브 클래스에서 접근 가능
constructor(public title: string, public author: string) {}
}
// LibraryBook 클래스는 Book 클래스를 상속 받는다.
class LibraryBook extends Book {
constructor(title: string, author: string) {
super(title, author);
}
public checkStatus() {
// 서브 클래스에서 접근 가능
return this.checkedOut ? 'Checked out' : 'Available';
}
}
const libraryBook = new LibraryBook('Deep Work', 'Cal Newport');
console.log(libraryBook.checkStatus()); // 'Available'
// console.log(libraryBook.checkedOut); // 오류 발생 (protected 속성은 클래스 외부에서 접근 불가)
축약 문법(Shorthand Syntax)
- 타입스크립트에서는 클래스 생성자에서 @public@, @private@, @protected@와 같은 접근자를 사용하여 더 간결하게 속성을 정의하고 초기화할 수 있다.
class Book {
private checkedOut: boolean = false;
constructor(public readonly title: string, public author: string) {}
}
Getter와 Setter
- Getter와 Setter는 클래스에서 속성의 접근 및 수정을 제어하는 특수한 메서드이다.
- 호출 시 함수처럼 사용되지 않고, 속성처럼 접근할 수 있다.
- 호출 할 때 소괄호(@()@)를 붙이지 않는다.
- Getter와 Setter로 만들고자 하는 메서드 이름 앞에 @get@ 또는 @set@ 키워드를 붙인다.
class Book {
private checkedOut: boolean = false;
constructor(public readonly title: string, public author: string) {}
// getter
get info() {
return `${this.title} by ${this.author}`;
}
// getter
get checkOut() {
return this.checkedOut;
}
// getter
public get someInfo() {
this.checkOut = true;
return `${this.title} by ${this.author}`;
}
// setter
private set checkOut(checkedOut: boolean) {
this.checkedOut = checkedOut;
}
}
const deepWork = new Book('Deep Work', 'Cal Newport');
// 호출할 때, 소괄호를 붙이지 않는다.
console.log(deepWork.info);
console.log(deepWork.someInfo);
console.log(deepWork.checkOut);
Getter와 Setter 메서드를 호출할 때, 소괄호(@()@)를 붙이지 않는다.
인터페이스 구현(Implementation of Interface)
- 타입스크립트에서 인터페이스(Interface)는 객체 구조에 대한 계약 조건(Contract)을 정의한다.
- 클래스가 인터페이스를 구현(Implementation)할 때, 그 클래스는 인터페이스에 정의된 모든 속성과 메서드를 제공해야 한다.
- 클래스에서 @implements@ 키워드를 이용하여 인터페이스를 구현할 수 있다.
interface IPerson {
name: string;
age: number;
greet(): void;
}
class Person implements IPerson {
constructor(public name: string, public age: number) {}
greet() {
console.log(`Hello, my name is ${this.name} and I'm ${this.age} years old.`);
}
}
const hipster = new Person('ShakeAndBake', 100);
hipster.greet();
클래스를 이용하여 인터페이스를 구현할 때, 클래스에서 '반드시' 인터페이스의 모든 속성과 메서드를 구현해야 한다.
참고 사이트
Documentation - Classes
How classes work in TypeScript
www.typescriptlang.org
728x90
728x90
'Programming > TypeScript' 카테고리의 다른 글
| [TypeScript] 환경 변수 타입 설정하기 (3) | 2024.12.09 |
|---|---|
| [TypeScript] 제네릭(Generic) (0) | 2024.10.12 |
| [TypeScript] 인터페이스(Interface) (0) | 2024.10.12 |
| [TypeScript] Zod 라이브러리 (0) | 2024.10.11 |
| [TypeScript] 타입 가드(Type Guard) (0) | 2024.10.10 |
| [TypeScript] 모듈 방식 사용하기 (0) | 2024.10.10 |
| [TypeScript] 인터페이스(Interface)와 타입 별칭(Type Alias) 비교 (0) | 2024.10.09 |
| [TypeScript] ! 연산자(Non-null Assertion Operator) (0) | 2024.08.20 |