TypeScript - Class

신태일·2024년 10월 16일

1. 클래스란 ?


  • object를 만드는 blueprint(청사진, 설계도)
  • 클래스 이전에 object를 만드는 기본적인 방법은 function이었다.
  • JS에도 class는 es6부터 가능 (이전엔 modifier, runtime 지원 feature 등이 조금 부족)
  • Ts에서는 클래스도 사용자가 만드는 타입의 하나.
    • class = 사용자가 만드는 type의 하나

2. Quick Start - class


  • class 키워드를 이용하여 클래스를 만들 수 있다.
  • class 이름은 보통 대문자를 이용한다
  • new를 이용하여 class를 통해 object(인스턴스)를 만들 수 있다.
  • constructor를 이용하여 object를 생성하면서 값을 전달할 수 있다.
  • this를 이용해서 만들어진 object를 가리킬 수 있다.
class Person {
	name;
	
	constructor(name: string) {
		this.name = name;
	}
}

const p1 = new Person('Tommy');

console.log(p1);

3. constructor & initialize


  • 생성자 함수가 없으면, 디폴트 생성자가 작용한다.
  • 프로퍼티를 선언하는 곳 또는 생성자에서 값을 할당하지 않는 경우에는 ? 을 붙혀서 유동성을 지니게 한다.
class Person {
	name: string = "Tommy";
	age: number;

	constructor(age?: number) {
		if (!age) {
			this.age = 20;
		} else {
				this.age = age;
		}
	}
}

const p1: Person = new Person(39);

const p2: Person = new Person();

console.log(p1); // p1.age = 39;
console.log(p1.age); // 39;

4. 접근 제어자 (Access Modifiers)


  • 클래스 내 프로퍼티의 접근 가능성 설정
  • 접근 제어자에는 public, private, protected가 있다.
    • public: 클래스 내부 외부 어디서든 접근이 가능함
    • private: 클래스 내부에서만 접근 가능, 상속받은 클래스에서 조차도 접근 불가
    • protected: 클래스 내부 & 상속받은 클래스까지 허용
  • 클래스 내부의 모든 곳에 (생성자, 프로퍼티, 메서드) 설정 가능하다.

5. initialization in constructor parameters


→ 생성자의 파라미터를 받아서 그 클래스의 프로퍼티로 초기화 하는 방법

class Person {
	public constructor(public name: string, private age: number) {
	}
}

const p1: Person = new Person('Tommy', 26);
console.log(p1);

6. Getters & Setters


class Person {
	public constructor(private _name: string, private age: number) {
	}
	// 얻어오기
	get name() {
		// return 필수
		// console.log('get');
		return this._name + 'Lee';
	}

	// 변경하기
	set name(n: string) {
		// 인자 필수
		// console.log('set');
		// count해서 몇번 set 되었는지 활용할 수도 있음
		this._name = n;
}

const p1: Person = new Person('Tommy', 26);
console.log(p1.name);  // getter 함수 적용

p1.name = 'Tommy';  // setter 함수 적용
console.log(p1.name);

7. readonly properties


  • set은 할 수 없고 get만 할 수 있는 method
  • readonly: 수정불가능하게 막아 놓을 때 사용
class Person {
	public readonly name: string = 'Tommy';
	private readonly country: string;
	constructor(private _name: string, private age: number) {
		// constructor 안에서만 설정가능
		this.country = 'Korea';
	}
}

8. Static Properties & Methods


class Department {
	// 정적 필드는 this로 접근이 불가능하다.
	// 무조건 클래스 이름 + '.'과 함께 쓰여야 한다.
	static fiscalYear = 2023;

	constructor(protected readonly id: string, public name: string) {
	
	}
	
	static createEmployee(name: string) {
		return { name: name };
	}

}

// 정적 메서드를 사용하면 인스턴스를 만들지 않고도 바로 class method를 사용할 수 있다.
const employee1 = Department.createEmployee('Tommy');
console.log(employee1, Department.fiscalYear);

9. Singletons


  • 어플리케이션이 실행되는 중간에 클래스로부터 단 하나의 오브젝트만 생성해서 실행하는 패턴.
class AccountingDepartment extends Department {
	private lastReport: string;
	private static instance: AccountingDepartment;

	private constructor(id: string, private reports: string[]) {
		super(id, 'Accounting');
		this.lastReport = reports[0]; 
	}

	static getInstance() {
		// 생성자가 private 생성자이므로 클래스 선언 내부에서 instance가 있으면 기존 인스턴스를 내보내고
		// 인스턴스가 없으면 새로운 인스턴스를 생성하여 내보낸다.
		if (AccountingDepartment.instance) {
			return this.instance;
		}
		this.instance = new AccountingDepartment('d2', []);
			return this.instance;
	}
}

...

const accounting = AccountingDepartment.getInstacne();

// 이미 기존 인스턴스 accounting이 있으므로 accounting2는 이전의 값으로 반환된다.
const accounting2 = AccountingDepartment.getInstacne();

10. 상속(inheritance)


  • 클래스가 다른 클래스를 가져다가 자신만의 속성을 추가해서 사용하는 것
class ITDepartment extends Department {
	admins: string[];
	constructor(id: string, admins: string[]) {
		// super 호출을 통해 기존 Department 클래스 생성자 호출
		super(id, 'IT');
		this.admins = admins;
	}
}

11. Abstract Classes


  • 완전하지 않은 객체를 상속을 통해서 완전하게 하게 사용.
  • 선언만으로 인스턴스화 되기에 개별적으로 선언은 불가능하고 추상클래스를 상속받은 클래스에서 구체적인 구현을 해줘야 함
abstract class Department {
	protected employees: string[] = [];

	constructor(protected readonly id: string, public name: string) {
	
	}

	// 추상 클래스의 추상 메소드
	abstract describe(this: Department): void;
}

...

class AccountingDepartment extends Department {
	
	...

	// 상속받는 클래스에서 추상 메서드에 대한 구체적인 기술
	describe() {
		console.log('Accouning Department - ID: ' + this.id);
	}
profile
노원거인

0개의 댓글