class Person {
name;
constructor(name: string) {
this.name = name; // this = 생성된 object 자신
}
}
const p1 = new Person('Jinju');
console.log(p1); // Person { name: 'Jinju' }
class Person {
name: string = 'Jinju'; // 선언 시 동시에 값 할당
age!: number; // 클래스 내부에서 할당을 미루고 싶을 때는 !를 붙인다
// 클래스에 생성자를 구현하지 않을 경우
// > 보이지는 않지만 디폴트 생성자가 자동으로 생성
// 하지만 개발자가 생성자를 따로 구현한다면
// 디폴트 생성자는 사라진다
// constructor(age: number) {
// this.age = age; > 이런식으로 쓰면 age에 !는 빼도 무방
// }
}
const p1 = new Person();
pl.age = 26; // undefined 뜨지 않으려면 클래스 외부에서 값 할당 해줘야 한다
console.log(p1.age);
const p1: Person = new Person(26);
const p2: Person = new Person();
p1, p2처럼 값을 넣어줄 수도 있고 안 넣어줄 수도 있게끔 한다면 오버로딩을 사용할 수 있겠으나 (참고로 JavaScript는 오버로딩 X)
constructor (age?: number) {
if (age === undefined) { this.age = 20; }
else { this.age = age; }
}
undefined 값이 number타입의 age에 할당되면 에러가 날 수 있으므로 조건문으로 한 번 걸러준다
class Person {
public name: string = 'Jinju';
private _age!: number;
public async init() {}
}
class Person {
name: sring;
age: number;
public constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
}
// 위 아래의 코드는 같은 동작을 한다
class Person {
public constructor(public name: string, public age: number) {}
}
class Person {
// _(언더바)를 붙여 getter와 setter 이름 중복 충돌을 피한다
public constructor(public _name: string, private age: number) {}
get name() {
return this._name;
}
set name(n: string) {
this._name = n;
}
}
만약 setter를 지정하지 않는다면 > read only가 된다
class Person {
public readonly name: string = 'Jinju';
private readonly country: string;
public constructor(private _name: string, private age: number) {
this.country = 'Korea'; // OK
}
hello() {
this.country = 'Canada'; // Error
}
}
readonly 키워드를 쓸 때는 public이든 private이든 초기화 되는 곳(생성자, 프로퍼티)에서만 값을 바꿀 수 있다.
👉 프로퍼티를 초기 값으로 고정하고 다른 값으로 변경하고싶지 않을 때
// class => Object
class Students {
// [index: string]: string; 으로 해도 되지만 좀 더 정확하게는
[index: string]: 'male' | 'female';
}
const aClass = new Stduents();
aClass.john = 'male';
aClass.will = 'male';
console.log(aClass);
// {john: 'male', will: 'male'}
const bClass = new Students();
bClass.chloe = 'female';
bClass.alex = 'male';
bClass.anna = 'female';
console.log(bClass);
// {chloe: 'female', alex: 'male', anna: 'female'}
👉 프로퍼티가 고정된 형태가 아니라 동적으로 들어오는 경우에 고려해볼 수 있는 사항
class Person {
public static CITY = 'Incheon';
public static hello() {
console.log('안녕');
}
public change() {
Person.CITY = 'Seoul';
}
}
// 클래스에다가 대고 바로 메소드나 프로퍼티 호출 가능
Person.hello();
Person.CITY;
const p1 = new Person();
// p1.hello(); > ERROR
어플리케이션 실행 중 클래스로부터 단 하나의 오브젝트만 생성해서 사용하는 패턴
class ClassName {
private static instance: ClassName | null = null;
// 매개체가 되어줄 getInstance 함수
public static getInstance(): ClassName {
// ClassName으로부터 만든 object가 있으면 그걸 리턴
// ClassName으로부터 만든 object가 없다면, 만들어서 리턴
if(ClassName.instance === null) {
// class 내부이므로 private 생성자 호출 가능
ClassName.instance = new ClassName();
}
return ClassName.instance;
}
private constructor() {}
}
// 생성자에 private 키워드가 붙었으므로 new 키워드 사용 불가
// const a = new ClassName();
// a = 최초로 만들어짐
const a = ClassName.getInstance();
// a로 인해 이미 생성되었으므로 그것을 리턴
// a와 b사이의 공유 오브젝트 > static
const b = ClassName.getInstance();
console.log(a === b); // true
// a와 b 둘은 완벽하게 같은 오브젝트임이 증명됨
class Parent {
constructor(protected _name: string, private _age: number) {}
public print(): void {
console.log(`이름은 ${this._name}이고, 나이는 ${this._age} 입니다.`);
protected printName(): void {
console.log(this._name);
}
}
}
const p = new Parent('Jinju', 26);
p.print(); // 이름은 Jinju이고, 나이는 26 입니다.
// 👉 생성자의 접근제어자가 protected, private 이어도 제대로 출력 됨 ✨
class Child extends Parent {
// 오버라이드 시 부모클래스의 접근제어자를 바꿔도 무방
// public _name = 'example';
public gender = 'male';
// 생성자도 오버라이드 가능
constructor(age: number) {
super('example', age); // < 부모의 생성자 호출
this.printName();
}
}
abstract class AbstractPerson {
protected _name: string = 'Jinju';
// abstract 메서드는 구현하지 않는다
// 미완성 메소드이므로 new 키워드로 생성 불가
abstract setName(name: string): void;
}
// new AbstractPerson(); > 불가능
// 상속을 이용해 완전한 클래스로 만든 뒤 사용가능
class Person extends AbstractPerson {
setName(name: string): void {
this._name = name;
}
}
const p = new Person();
p.setName('Jinju');