Typescript

타입스크립트 입문!2 메모장

변기원 2022. 6. 29. 21:20

 

인스턴스

// app.ts

class Singer{
  name: string;
  age: number;
  singTitle: string;
  albumCount:number;

  printSingerInfo = (): void => {
     console.log(`${this.name}은 ${this.age}살이고, 현재까지 ${this.albumCount}개의 앨범을 냈습니다. 최근  ${this.name}가 낸 대표곡의 이름은 ${this.singTitle}이라는 노래입니다.`)
  }
}

let singer1:Singer = new Singer();
singer1.name='KSY';
singer1.age=26;
singer1.albumCount: 7;
singer1.singTitle: 'Dont know'
singer1.printEmployeeDetails(); // Singer 내부의 method에 접근 가능.

클래스(Singer)를 이용해서 인스턴스(singer1)를 만들어냈다.

바로 그 붕어빵 틀로 붕어빵을 만들어 낸 거다.

근데 각 프로퍼티를 하나씩 입력해야 해서 너무 불편하다.

 

생성자 (Constructor)

모든 Class는 constructor라는 method를 가질 수 있다. 

constructor는 class로부터 객체(인스턴스)를 생성할 때 호출된다.

객체(인스턴스)의 초기화를 담당한다.

// app.ts

class Singer{
  name: string;
  age: number;
  singTitle: string;
  albumCount:number;
  
  constructor(name: string, age: number, singTitle: string, albumCount: number)   {
    this.name= name;
    this.age= age;
    this.singTitle= singTitle;
    this.albumCount= albumCount;
  } // constructor 생성
  

  printSingerInfo = (): void => {
     console.log(`${this.name}은 ${this.age}살이고, 현재까지 ${this.albumCount}개의 앨범을 냈습니다. 최근  ${this.name}가 낸 대표곡의 이름은 ${this.singTitle}이라는 노래입니다.`)
  }
}

let singer1:Singer = new Singer('KSY',26,'Dont Know',7); // 간단한 객체 생성

singer1.printSingerInfo();

깔끔해졌다.

주의: 생성자가 존재하는 클래스를 통해 인스턴스를 만들 때는 반드시 생성자에 정의된 매개변수 값이 전달되어야 한다.

 

생성자(constructor)의 선택적 매개변수

// app.ts

constructor(name: string, age: number, singTitle: string, albumCount?: number){
    this.name= name;
    this.age= age;
    this.singTitle= singTitle;
    this.albumCount= albumCount;
  }

동일한 방법이다. 역시 옵셔널 매개변수는 가장 뒤에 있어야 한다.

// app.ts

let singer1:Singer = new Singer('KSY',26,'Dont Know',7); // 간단한 객체 생성
singer1.name='PMC'  // singer1의 name 재할당

클래스로 만든 객체의 name을 재할당했고. 잘 변경이 된다.

때때로 외부로부터 데이터를 보호해야 할 필요가 있다. 객체의 프로퍼티에 접근하는 것을 막아야 하는 경우가 있다.

이때 사용하는 게 접근 제한자이다.

 

접근 제한자 (Access Modifier)

클래스의 프로퍼티와 메서드에 적용되는 키워드로써 외부로부터 접근을 통제하는 역할을 한다.

버그를 줄여주고 코드를 안정화시킬 수 있다.

종류로는 public, protected, private가 있다.

Public

public 키워드가 붙은 변수는 클래스 외부에서 접근이 가능하다. 디폴트 값이다. 

Protected

클래스 내부, 상속받는 자식 클래스에서 접근이 가능하다.

Private

오직 클래스 내에서만 접근이 가능하다. 외부에서는 접근이 불가능

private가 붙은 변수들은 앞에 _ 를 붙여주는 컨벤션이 있다.

// app.ts

class Singer{
  private _name: string; // name 멤버를 private로 선언
  age: number;
  singTitle: string;
  albumCount:number;
  
  constructor(name: string, age: number, singTitle: string, albumCount: number)   {
    this.name= name;
    this.age= age;
    this.singTitle= singTitle;
    this.albumCount= albumCount;
  } 
  

  printSingerInfo = (): void => {
     console.log(`${this._name}은 ${this.age}살이고, 현재까지 ${this.albumCount}개의 앨범을 냈습니다. 최근  ${this.name}가 낸 대표곡의 이름은 ${this.singTitle}이라는 노래입니다.`)
  }
}

let singer1:Singer = new Singer('KSY',26,'Dont Know',7); 
singer1.name='PMC'  // singer의 name은 private 요소임으로 에러 발생
singer1.printSingerInfo();

name이 private가 되었으므로 클래스 외부에서 재할당이 불가능. 에러 발생

// app.ts

console.log(singer1.name); //에러 발생

심지어 private는 접근 자체를 막기 때문에 출력도 불가능. 

이것을 실행시키려면 어떻게 해야 할까

 

Getter와 Setter

// app.ts

class Singer{
  private _name: string; // name 멤버를 private로 선언
  age: number;
  singTitle: string;
  albumCount: number;
  
  constructor(name: string, age: number, singTitle: string, albumCount: number)   {
    this.name= name;
    this.age= age;
    this.singTitle= singTitle;
    this.albumCount= albumCount;
  } 
  
  get name () {   // Getter
    return this._name;
  }
  
  set name (value: string) {  //Setter
    this._name=value;
  }
  

  printSingerInfo = (): void => {
     console.log(`${this._name}은 ${this.age}살이고, 현재까지 ${this.albumCount}개의 앨범을 냈습니다. 최근  ${this.name}가 낸 대표곡의 이름은 ${this.singTitle}이라는 노래입니다.`)
  }
}

let singer1:Singer = new Singer('KSY',26,'Dont Know',7); 
console.log(singer1.name); // get name을 통해 가능해짐
singer1.name='PMC' // set name을 통해 가능해짐.

singer1.printSingerInfo();

근데 클래스 밖에서 get도 가능하고 set도 가능할 거면 왜 private를 설정한 걸까..?

 

Constructor에서의 Access Modifiers

위 작성 코드는 멤버가 constructor 외부에서도 선언되고, 내부에서도 선언되고 상당히 장황하고 반복되며 보기 좋지 않음을 알 수 있습니다. 이러한 것들을 constructor 내부에 다 정의하고 Access Modifiers 또한 constructor 내부에서 적용할 수 있습니다.

// app.ts

class Singer{
  //기존의 property들 삭제
  constructor(
   private _name: string, 
   private _age: number, 
   private _singTitle: string, 
   public albumCount: number){ 
  } 
  
  get name () {   // Getter
    return this._name;
  }
  
  set name (value: string) {  //Setter
    this._name=value;
  }
  

  printSingerInfo = (): void => {
     console.log(`${this._name}은 ${this.age}살이고, 현재까지 ${this.albumCount}개의 앨범을 냈습니다. 최근  ${this.name}가 낸 대표곡의 이름은 ${this.singTitle}이라는 노래입니다.`)
  }
}

let singer1:Singer = new Singer('KSY',26,'Dont Know',7); 

singer1.printSingerInfo(); 

생성자 constructor에 전달된 매개변수는 암묵적으로 객체의 프로퍼티 값으로 초기화, 할당된다. 

그러니까 아까처럼 두 번 작성할 필요 없다,

그리고 생성자 내부에서도 접근 제한자가 적용된다. 

 

 

출처:

https://velog.io/@kysung95/TS-TypeScript-%EA% B0% 9C% EB% A1% A0-5

 

[TS] TypeScript 개론 (5)

TypeScript 개론의 그 마지막 포스팅입니다.이번 포스팅에서는 TypeScript의 Class와 객체에 대해 설명드린 후 생성자, 접근 제한자에 대해 설명드리겠습니다.

velog.io