자바스크립트의 클래스 소개
- 클래스는 동일한 모양의 객체를 더 쉽게 생성하도록 도와주는 문법이다.

- 이처럼 여러명의 학생을 객체로 나타내게되면 프로퍼티의 값만 조금씩 다를뿐 동일한 프로퍼티를 가진다.
- 즉, 동일한 모양의 객체라고 볼 수 있다. 그래서 중복 코드가 발생하게된다.
- 이때 자바스크립트의 클래스 라는 문법을 사용하면 도움이 된다.
클래스 선언하기
- 클래스 선언은 다음과 같다.

- 클래스는 객체를 생성하는 틀이다.
- 클래스를 선언하면 필드를 선언한다.
필드란 클래스가 생성할 객체가 갖는 프로퍼티를 의미한다.
- 필드를 선언하고 나면 생성자를 선언한다.
생성자는 특수한 메서드로 실질적으로 객체를 생성하는 함수이다.
- 생성자에서는 매개변수로 프로퍼티 값을 받아 this.프로퍼티의 값으로 할당한다.
- 이때
this는 객체이며 현재 만들고 있는 객체를 의미한다. 따라서 이 생성자 메서드는 현재 만들고 있는 객체의 name, grade, age 프로퍼티의 값을 매개변수로 전달받은 값으로 설정하는 역할을 한다.
- 이렇게 생성자를 만들면 이 클래스를 호출하여 객체를 생성할 수 있다.

- 클래스를 이용해 새로운 객체를 생성할 때에는
new 클래스이름 형태로 클래스의 생성자 함수를 호출한다. 이때 인수로는 각각 name, grade, age를 전달한다.
- 그럼 생성자가 호출되어 this.name에는 매개변수 name에 저장된 “홍길동”을 this.grade에는 매개변수 grade에 저장된 “A+”를 this.age에는 매개변수 age에 저장된 27을 저장한다.
- 그러면 다음과 같이 생긴 객체를 생성한다.
{ name: "홍길동", grade: "A+", age: 27 }
- 이렇게 클래스를 이용해서 만든 객체를 인스턴스라고 부른다.

- 이와 같은 방법으로 클래스가 생성할 객체의 메서드도 설정할 수 있다.
- 주의할 점은 클래스를 생성할때 쉼표를 활용하지 않는다는 점!
this 활용하기
- 클래스 내부에서 this는 현재 만들고 있는 객체를 의미한다.
- 따라서 메서드에 다음과 같이 this를 활용해 객체 프로퍼티의 값을 활용하는 것 또한 가능하다.

상속
- 만약 앞서 만든 Student 클래스를 기반으로 추가적인 필드와 메서드를 갖는 클래스를 선언하고 싶다면 다음과 같이 상속을 이용하면 된다.

- StudentDeveloper 클래스는 Student 클래스를 확장(상속)한다.
- 이 확장은 인터페이스의 확장과 기본적으로 비슷하다. 따라서 Student 클래스에 정의된 모든 필드와 메서드를 자동으로 갖게된다.
- StudentDeveloper 클래스만의 새로운 필드나 메서드도 위와 같이 정의할 수 있다.
- 그런데 이때 StudentDeveloper 클래스에서 Student 클래스의 생성자를 함께 호출해줘야 한다. 그렇지 않으면 생성되는 객체의 name, grade, age 값이 제대로 설정되지 않는다. 따라서 super 라는 메서드를 호출한다.
- super를 호출하고 인수로 name, grade, age를 전달하면 슈퍼 클래스(확장 대상 클래스)의 생성자를 호출한다. 따라서 this.name, this.grade, this.age의 값을 설정하게 된다.
타입스크립트의 클래스
- 타입스크립트에서는 클래스의 필드를 선언할 때 타입 주석으로 타입을 함께 정의해주어야 한다.
- 그렇지 않으면 함수의 매개변수와 동일하게 암시적 any 타입으로 추론되는데, 엄격한 타입 검사 모드(strict 옵션이 true로 설정되어 있을 경우)일 때에는 오류가 발생하게 된다.
- 추가로 생성자에서 각 필드의 값을 초기화 하지 않을 경우, 초기값도 함께 명시해주어야 한다.
- 만약 생성자 함수에서 필드의 값들을 잘 초기화 해준다면 필드 선언시의 초기값은 생략해도 된다.

- 이때 만약 이 클래스가 생성하는 객체의 특정 프로퍼티를 선택적 프로퍼티로 만들고 싶다면 필드의 이름 뒤에 물음표를 붙여주면된다.
클래스는 타입입니다.
- 타입스크립트의 클래스는 타입으로도 사용할 수 있다. 클래스를 타입으로 사용하면 해당 클래스가 생성하는 객체의 타입과 동일한 타입이 된다.

- 변수 employeeC의 타입을 Employee 클래스로 정의했습니다. 따라서 이 변수는 name, age, position 프로퍼티와 work 메서드를 갖는 객체 타입으로 정의된다.
상속
- 타입스크립트에서 클래스의 상속을 이용할 때 파생 클래스(확장하는 클래스)에서 생성자를 정의 했다면 반드시 super 메서드를 호출해 슈퍼 클래스(확장되는 클래스)의 생성자를 호출해야 하며, 호출 위치는 생성자의 최상단 이어야만 한다.

접근 제어자(Access Modifier)
- 타입스크립트에서만 제공되는 기능으로 클래스의 특정 필드나 메서드를 접근할 수 있는 범위를 설정하는 기능이다.
- 타입스크립트에서는 다음과 같은 3개의 접근 제어자를 사용할 수 있다.
public : 모든 범위에서 접근 가능
private : 클래스 내부에서만 접근 가능
proteced : 클래스 내부 또는 파생 클래스 내부에서만 접근 가능
public
public은 공공의~ 라는 뜻으로 어디서든지 이 프로퍼티에 접근할 수 있음을 의미한다.
-> 그래서 아래 코드의 마지막 줄 처럼 인스턴스의 프로퍼티에 자유롭게 접근이 가능한 것이다.
- 앞서 만들었던 클래스와 같이 필드의 접근 제어자를 지정하지 않으면 기본적으로 public 접근 제어자를 갖게 됩니다.

- 물론 public 접근 제어자를 직접 명시하는 것도 가능하다!
private
private은 제한된, 사적인 이라는 뜻으로 특정 필드나 메서드의 접근 제어자를 private으로 설정하면 클래스 내부에서만 이 필드에 접근할 수 있게 된다.

- name 필드를 private으로 설정했으므로 클래스 외부에서는 접근이 불가하다.
- 그러나 클래스 내부에서는 work 메서드 처럼 접근이 자유롭게 가능하다.
- 하지만 이렇게 private로 설정하면 파생된 클래스에도 접근이 불가능하다.
protected
proteced 접근제어자는 private과 public의 중간으로 클래스 외부에서는 접근이 안되지만 클래스 내부와 파생 클래스에서 접근이 가능하도록 설정하는 접근 제어자이다.

- Employee 클래스를 확장(상속)하는 파생 클래스 ExecutiveOfficer를 선언한 다음 메서드 func를 만들었다.
- 이 메서드에서는 name과 age에 접근하는데 이때 name은 private으로 접근이 불가하지만, age는 protected이므로 파생 클래스에서는 접근이 가능하다. 그러나 클래스 외부에서는 접근이 불가하다.
필드 생략하기
- 접근 제어자는 다음과 같이 생성자의 매개변수에도 설정할 수 있다.
- 그러나 생성자에 접근 제어자를 설정하면 동일한 이름의 필드를 선언하지 못하게 된다. 그 이유는 생성자 매개변수에 name, age, position 처럼 접근 제어자가 설정되면 자동으로 필드도 함께 선언되기 때문이다. 따라서 동일한 이름으로 필드를 중복 선언할 수 없게 된다.

- 따라서 다음과 같이 중복된 필드 선언을 모두 제거해 주어야 한다.
- 접근 제어자가 설정된 매개변수들은
this.필드 = 매개변수가 자동으로 수행된다. 따라서 위 코드의 name, age, position은 모두 this 객체의 프로퍼티 값으로 자동 설정되기 때문에 다음과 같이 생성자 내부의 코드를 제거해도 된다.

- 그러므로 타입스크립트에서 클래스를 사용할 때에는 보통 생성자 매개변수에 접근 제어자를 설정하여 필드 선언과 생성자 내부 코드를 생략하는것이 훨씬 간결하고 빠르게 코드를 작성할 수 있어 좋다.
인터페이스와 클래스
- 타입스크립트의 인터페이스는 클래스의 설계도 역할을 할 수 있다.
- 쉽게말해 다음과 같이 인터페이스를 이용해 클래스에 어떤 필드들이 존재하고, 어떤 메서드가 존재하는지 정의할 수 있다.

- Character 클래스는 CharaterInterface를 구현한다는 뜻이다.
- 인터페이스 CharacterInterface는 name, moveSpeed 프로퍼티와 move 메서드를 갖는 객체 타입을 정의한다. 그런데 이 인터페이스를 클래스에서
implements 키워드와 함께 사용하면 이제부터 이 클래스가 생성하는 객체는 모두 이 인터페이스 타입을 만족하도록 클래스를 구현해야한다.
- 주의할 점은 Interface로 정의하는 필드들은 무조건
public을 사용해야한다. 그래서 private를 사용하고 싶다면 Interface가 아니라 클래스안에 직접 정의해줘야한다.
이미지 출처: <한 입 크기로 잘라먹는 타입스크립트>
https://www.inflearn.com/course/%ED%95%9C%EC%9E%85-%ED%81%AC%EA%B8%B0-%ED%83%80%EC%9E%85%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8?inst=68d752f7&utm_source=instructor&utm_medium=referral&utm_campaign=inflearn_%ED%8A%B8%EB%9E%98%ED%94%BD_promotion-link