[TypeScript] 섹션6. 클래스

jaehoon ahn·2025년 2월 12일

TypeScript

목록 보기
9/14
post-thumbnail

자바스크팁트의 클래스 소개

클래스

let studentA = {
  name: "제노",
  grade: "A+",
  age: 27,
  study() {
    console.log("열심히 공부 함");
  },
  introduce() {
    console.log("안녕하세요!");
  },
};
let studentB = {
  name: "비노",
  grade: "B-",
  age: 27,
  study() {
    console.log("열심히 공부 함");
  },
  introduce() {
    console.log("안녕하세요!");
  },
};
  • 똑같은 프로퍼티를 갖고있고, 값만 다름
  • 동일한 형식, 모양의 객체를 여러개 만들어야 하면 중복 코드가 발생
  • 만약, 수십, 수백명 학생의 객체를 만들어야 할 때, 굉장히 불편함
  • 이때, js 클래스를 이용하면 좋다.

⇒ 즉, 객체를 찍어내는 틀

클래스 정의 방법

class Student {
  // 필드: 클래스가 만들어 낼 객체 프로퍼티를 의미
  // 어떤 모양의 객체를 찍어낼지 정의하는 것
  name;
  grade;
  age;

  // 생성자
  //   클래스를 호출하면, 실제로 객체를 생성하는 역할을 하는 함수
  constructor(name, grade, age) {
    this.name = name;
    this.grade = grade;
    this.age = age;
    // this는 클래스가 지금 만들고 있는 객체
  }
  //   메서드
  //   Student 클래스로 만들어지는 인스턴스는 study, introduce를 갖게 됌
  study() {
    console.log("열심히 공부 함");
  }
  introduce() {
    console.log(`안녕하세요! ${this.name} 입니다!`);
  }
}

클래스를 호출해서 객체 생성하는 방법

let studentB = new Student("제노", "A+", 27);
  • 클래스를 이용해서 만든 객체 → 인스턴스

⇒ 즉, 스튜던트 인스턴스라고 부를 수 있다.

메서드 사용법

studentB.study();
studentB.introduce();

상속

class StudentDeveloper extends Student {
  // 필드
  favoriteSkill;

  // 생성자
  constructor(name, grade, age, favoriteSkill) {
    super(name, grade, age);
    // super로 name, grade, age 인수로 전달해줘야 한다.
    // 메서드, 필드를 가져오지만, 생성자에서는 name, grade, age 프로퍼티 값이 설정이 되지 않기 때문에,
    // super를 호출해서 넘겨주면 부모 클래스(Student)의 생성자가 호출된다.
    this.favoriteSkill = favoriteSkill;
  }
  // 메서드

  programming() {
    console.log(`${this.favoriteSkill}로 프로그래밍 함`);
  }
}

const studentDeveloper = new StudentDeveloper("제노", "B+", 27, "TypeScript");
console.log(studentDeveloper);
studentDeveloper.programming();
  • 위와 같이 extends를 사용해주면 된다.
  • 생성자는 super를 통해 상위 클래스의 필드를 가져올 수 있다.

타입스크립트의 클래스

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("일함");
  }
}

TypeScript에서의 상속

class ExecutiveOfficer extends Employee {
  // 필드
  officeNumber: number;

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

인스턴스 생성

const employeeB = new Employee("제노", 27, "개발자");
console.log(employeeB);
  • TypeScript에서 클래스는 js 클래스로 취급되면서 동시에 타입으로 취급이 된다.
  • TypeScript는 구조적으로 타입을 결정하는 구조적 타입 시스템을 따른다.
  • 클래스의 구조를 보고 필드, 메서드가 있으면 해당 타입으로 하자! 라고 결정을 하기 때문이다.
const employeeC: Employee = {
  // 필드, 메서드를 갖고 있어야 함.
  name: "",
  age: 0,
  position: "",
  work() {},
};

접근 제어자

⇒ access modifier

⇒ 종류로는 public, private, protected

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

  // 생성자
  constructor(
    name: string,
    age: number,
    position: string
  ) {
    this.name = name;
    this.age = age;
    this.position = position;
  }
  // 메서드
  work() {
    console.log(`${this.name} 일함`);
  }
}

접근 제어자를 통해 사용할 수 있는 기능

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

  // 생성자
  constructor(
    private name: string,
    protected age: number,
    public position: string
  ) {
    // this.name = name;
    // this.age = age;
    // this.position = position;
    //  
  }
  // 메서드
  work() {
    console.log(`${this.name} 일함`);
    // private: 사적인, 외부에서는 프로퍼티에 접근하는 것, 읽는 것 조차도 불가능 해진다. -> 내부에서는 가능
  }
}

employee.name = "홍길동"; // 오류 발생
// private: 사적인, 외부에서는 프로퍼티에 접근하는 것, 읽는 것 조차도 불가능 해진다. 
// -> 내부에서는 가능
// private으로 설정하면 오류가 발생

필드

  • 생성자에서 접근 제어자를 사용했을 경우 생략 가능

생성자

  • 생성자에도 접근 제어자 사용 가능
  • 접근 제어자를 사용했을 경우 자동으로 필드를 TypeScript가 만들어줌
  • 필드의 값 초기화도 자동으로 진행해서, 초기화를 안해도 된다.

⇒ 따라서, 필드 영역을 작성할 필요가 없다.

⇒ 작성하면 오히려 중복되었다고 오류가 발생

파생 클래스

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;
    // protected: 외부에서 접근이 불가능 해지지만, 
    // 파생 클래스 내부에서 접근이 가능하도록 하고 싶을 때 사용
  }
}

정리

  • public: 공공의, 즉 모두 오픈되어 있다는 것, 아무 제약이 없는 상태(default값)
  • private: 슈퍼 클래스 내부에서는 접근이 가능하나, 외부에서는 읽기, 수정이 안된다.
  • protected: 파생 클래스 내부에서 접근이 가능, 외부에서는 불가능

인터페이스와 클래스

// 인터페이스와 클래스

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

// interface 타입의 객체를 생성할 수 있도록 정의할 수 있다.
class Character implements CharacterInterface {
  constructor(public name: string, public moveSpeed: number) {}
  //   constructor(private name: string, protected moveSpeed: number) {}
  // 이렇게 private, protected를 접근 제어자를 설정하면, 오류가 발생
  // 인터페이스는 무조건 public 필드만 정의할 수 있기 때문
  move() {
    console.log(`${this.moveSpeed} 속도로 이동!`);
  }
}
  • 인터페이스는 무조건 public 필드만 정의할 수 있다.

0개의 댓글