타입스크립트 - 클래스

드엔트론프·2023년 8월 3일
0

typescript

목록 보기
8/12
post-thumbnail

들어가며

  • 리액트를 사용하다보면 클래스에 대해 마주할 일이 그리 많지 않은 것 같다. 그래도 일부 라이브러리나 가끔가다 클래스를 쓸 일이 생기곤 한다. 최근에 바닐라 자바스크립트를 만지다 생성자 함수로 불러오는 걸 클래스로 바꾸고 타입을 적용해보는 일이 있었는데, 음 내가 사용하는 정도는 그정도였던 것 같다.

클래스

class Student {
  // 필드 - 클래스가 만들어낼 객체의 프로퍼티를 정의하는 것
  name;
  grade;
  age;

  //생성자 - 클래스를 호출하면 실제로 객체를 만드는 메서드
  constructor(name, grade, age) {
    this.name = name;
    this.grade = grade;
    this.age = age;
  }
  //메서드
  study() {
    console.log("study hard");
  }
  introduce() {
    console.log(`hi~ I'm ${this.name}`);
  }
}
  • 자바스크립트로 썼을 때의 클래스 형태는 위와 같다.
class Employee {
  //필드
  name: string;
  age: number;
  position: string;

  constructor(name: string, age: number, position: string) {
    this.name = name;
    this.age = age;
    this.position = position;
  }

  work() {
    console.log("working");
  }
}
  • 타입스크립트 클래스 기본 형태
class ExecutiveOfficer extends Employee {
  // 필드
  officeNumber: number;

  constructor(
    name: string,
    age: number,
    position: string,
    officeNumber: number
  ) {
    super(name, age, position);
    this.officeNumber = officeNumber;
  }
}
  • 상속 시 타입을 적용한 클래스 형태.
  • Employee의 내용을 그대로 상속받을 때는, 생성자인 Constructor에 매개변수로 담고, 또 super 를 사용하여 Employee에서 받아온 값들을 다 작성해주어야 한다.

접근 제어자

class Employee {
  //필드
  private name: string;
  protected age: number;
  position: string;

  constructor(name: string, age: number, position: string) {
    this.name = name;
    this.age = age;
    this.position = position;
  }

  work() {
    console.log("working");
  }
}

접근 제어자란 말 그대로 접근을 어디까지 줄 지 말하는 것이다.

  • 만약 name에 private 이라고 붙이게 되면, class 바깥에선 name을 접근할 수 없다.

name private 1

  • 그런데, 이렇게 Private을 하게되면 상속받은 다른 클래스에서도 사용을 할 수 없다.
class ExecutiveOfficer extends Employee {
  // 필드
  officeNumber: number;

  constructor(
    name: string,
    age: number,
    position: string,
    officeNumber: number
  ) {
    super(name, age, position);
    this.officeNumber = officeNumber;
  }

  func(){
    this.name //에러
    this.age
  }
}

name private 2

  • 이렇게 상속받은 곳에서는 사용하고 싶다면, protected 를 써주면 된다.
  • 그러면 class 외부에선 접근할 수 없고, 상속받은 클래스에서는 사용할 수 있다.

    추가로, constructor에 접근 제어자를 붙이게 되면 필드값이 자동으로 생성되기때문에 필드값을 적지 않아도 된다.

constructor에 접근제어자

  • 또, constructor 아래에 this.name = name 과 같이 명시하는 것 또한 자동으로 해주기에 지워도 된다 !
  • 그래서 아래처럼 적어도 오류가 나지 않음을 알 수있다.
class Employee {
  constructor(
    protected name: string,
    protected age: number,
    public position: string
  ) {}

  work() {
    console.log("working");
  }
}
  • 상속받은 클래스는 그래도 super 써줘야 한다.
class ExecutiveOfficer extends Employee {
  constructor(
    protected name: string,
    protected age: number,
    public position: string,
    public officeNumber: number
  ) {
    super(name, age, position);
  }

  func() {
    this.name;
    this.age;
  }
}

인터페이스와 클래스

  • 인터페이스와 클래스를 같이 쓰는 방법이 있다. 실제로 그렇게 많이 쓰진 않겠지만, 라이브러리 같은 거 쓸 때 보면 같이 쓰이는 게 은근 있다. 알아두면 좋을 것.
/**
 * 인터페이스와 클래스
 */

interface CharacterInterface {
  name: string;
  moveSpeed: number;
  move(): void;
}

class Character implements CharacterInterface {
  name: string;
  moveSpeed: number;

  constructor(name: string, moveSpeed: number) {
    this.name = name;
    this.moveSpeed = moveSpeed;
  }

  move(): void {
    console.log(`${this.moveSpeed} 속도로 이동`);
  }
}
  • class 옆에 implements 라는 걸로 인터페이스를 정의해주면 된다. 그리고 바로 지난 시간에 배운 접근 제어자를 constructor 매개변수에 붙여주면 훨씬 깔끔하게 작성할 수 있다.
interface CharacterInterface {
  name: string;
  moveSpeed: number;
  move(): void;
}

class Character implements CharacterInterface {
  constructor(public name: string, public moveSpeed: number) {}

  move(): void {
    console.log(`${this.moveSpeed} 속도로 이동`);
  }
}

주의할점! 인터페이스로 정의된 값들은 public 이다. 무조건 !

  • 굳이 private이나 protected를 쓰고 싶다면, 클래스에서 직접 정의하면 된다.
profile
왜? 를 깊게 고민하고 해결하는 사람이 되고 싶은 개발자

0개의 댓글