Class

1,571 단어·4 분·원문(.md)

  • object를 만드는 blueprint
  • 클래스 이전에 object를 만드는 기본적인 방법은 function
  • JavaScript에도 class는 ES6 부터 사용가능
  • OOP 을 위한 초석
  • TypeScript 에서는 클래스도 사용자가 만드는 타입의 하나. JS 보다 강력.
  • class = 사용자가 만드는 type의 하나

class #

  • class 키워드를 사용하여 클래스를 만들 수 있다.
  • 이름은 보통 대문자를 이용한다.
  • new를 이용해서 object를 만들 수 있다.
  • constructor를 이용하여 object를 생성하면서 값을 전달할 수 있다.
  • this 를 이용해서 만들어진 object를 가리킬 수 있다.
  • js로 컴파일되면 es5의 경우 function으로 변경된다.
class Person {
  name;
  constructor(name : string){
    this.name = name;
  }
}

const p1 = new Person("Minuuuk");

constructor & initialize #

  • 생성자 함수가 없으면 , 디폴트 생성자가 불린다.
  • 프로그래머가 만든 생성자가 하나라도 있으면 , 디폴드 생성자는 사라진다.
  • strict 모드에서는 프로퍼티를 선언하는 곳 또는 생성자에서 값을 할당해야 한다.
  • 클래스의 프로퍼티가 정의되어 있지만, 값을 대입하지 않으면 undefined 이다.
  • 생성자에는 async를 설정할 수 없다.
class Person{
  name : string = "mark"
  age : number;

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

const p1 : Person = new Person(17);
const p2 : Person = new Person();

접근 제어자 #

  • 클래스 내 프로퍼티의 접근 가능성 설정.
  • 접근 제어자에는 public, private , protected가 있다.
  • 설정하지 않으면 public 이다.
  • 클래스 내부의 모든 곳에 (생성자 , 프로퍼티 , 메서드) 설정 가능하다.
  • pricate 으로 설정하면 클래스 외부에서 접근할 수 없다.
  • 자바스크립트에서 private를 지원하지 않아 오랫동안 프로퍼티나 메서드 이름 앞에 _를 붙여서 표현했다.
class Person {
  public name : string = "Huemang";
  private age : nuber;

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

  public async init(){

  }
}

const p1: Person = new Person(17);

initialization in constructor parameters #

  • 생성자의 파라미터를 받아서 그 클래스의 프로퍼티로 초기화 하는 방법.
class Person {
  public constructor(public name : string , private age : number){}
}

const p1 : Person = new Person("Mark",39);
console.log(p1);

Getters & Setters #

class Person {
  public constructor(private _name : string , private age : number){}
  get name(){
    // return 필수
    return this._name + "Kim"
  }

  set name(n : string){
    // count를 사용해 몇번 set되었는지 체크가능.
    this._name = n;
  }
}


const p1: Person = new Person("Mark", 39);
console.log(p1.name); // Get, get을 하는 함수 : getter
p1.name = 'Woongjae'; // Set, set을 하는 함수 : setter
console.log(p1.name);

readonly properties #

  • set은 할 수 없고 get만 할 수 있는 메서드
  • readonly : 수정불가능하게 막아 놓을 때 사용한다.
class Person{
  public readonly name : string = 'Mark';
  private readonly country : string;
  public constructor(private _name : string, private age : number){
    this.country = "Korea";
  }
  hello(){
    // readonly 이고 private이므로 수정 불가
    //this.country = "japan";
  }
}
const p1 : Person = new Person("huemang" , 17);

8. Index Signatures in class #

  • property가 고정된 것이 아닌 동적으로 바뀌는 상황에서 고려해볼 만한 부분.
class Students {
  [index : string] : 'male' | 'female';

  mark : "male" = "male";
}

const a = new Students();
a.mark = "male";
a.jade = "male";

const b = new Students();
b.chloe = "female";
b.alex = "male";
b.anna = "femal

Static Properties & Methods #

class Person {
  public static CITY = "Seoul";
  public hello(){
    console.log("안녕하세요 ! " , Person.CITY);
  }
  public change() {
    Person.CITY = "LA";
  }
}

const p1 = new Person();
p1.hello(); // 안녕하세요 Seoul

const p2 = new Person();
p2.hello(); // 안녕하세요 Seoul
p1.change(); // 'LA로 변경'
p2.hello(); // 안녕하세요 LA

// static : 공통적으로 사용할 부분들.
// Person.hello();
// Person.CITY;

Singletons #

  • 어플리케이션이 실행되는 중간에 단 클래스로부터 단 하나의 오브젝트만 생성해서 실행하는 패턴
class ClassName{
  private static instance : ClassName | null = null;
  // private 로 new 로 직접 생성할 수 없도록 막음.
  public static getInstance(){
    // ClassName 으로부터 만든 Object가 있으면 그걸 리턴
    // 없으면, 만들어서 리턴.
    if(ClassName.instance === null){
      ClassName.instance = new ClassName();
    }

    return ClassName.instance;
  }
  private constructor(){}
}

const a = ClassName.getInstance();
const b = ClassName.getInstance();

console.log(a === b); // true

상속 #

  • 클래스가 다른 클래스를 가져다가 자신만의 속성을 추가해서 사용하는 것.
class Parent{
  // protected : 외부에서는 사용 불가하지만 상속하면 사용 가능.
  constructor(protected _name: string , private _age : number){}

  public print() : void {
    console.log(`내이름은 ${this._name} 이고, 나이는 ${this._age} 입니다. `);
  }

  protected printName() : void {
    console.log(this._name, this._age)
  }
}

// const p = new Parent("Makr", 17);
// p.print(); 이름은 Mark이고 , 나이는 39입니다.

class Child extends Parent {
  // Parent의 생성자를 그대로 가져옴.
  public gender = 'male';
  // override
  // public _name = "Mark Jr";
  // 생성자 override
  constructor(age : number){
    super('Mark Jr', age)
    this.printName();
  }
}

const c = new Child(1);
c.print()
// Mark Jr. 1
// 이름은 Mark Jr. 이고 , 나이는 1 입니다.

// 애플리케이션이 복잡해지면 부모와 자식의 영역에서 각각 할 수 있는 것을 계획하고 구분하는 것이 좋음.

Abstract Classes #

  • 완전하지 않는 객체를 상속을 통해서 완전하게 하여 사용.
abstract class AbstractPerson{
  protected _name : string = 'Mark';

  abstract setName(name : string) : void;

  // new AbstractPerson() x
}

class Person extends AbstractPerson{
  setName(name : string) : void {
    this._name = name;
  }
}

const p = new Person();
Front-End/JS/TS_class.md