[study:러닝 타입스크립트] 08. 클래스

const job = '프론트엔드';·2023년 5월 24일
0

타입스크립트

목록 보기
7/8
post-thumbnail

여덟번째. 클래스

8.1 클래스 메서드

타입스크립트는

  • 독립 함수(standalone function)을 이해하는 것과 동일한 방식으로 메서드를 이해함

독립함수(standalone function) ?

  • 클래스나 객체에 속하지 않고 독립적으로 정의된 함수로,
    전역 범위에 정의되거나 모듈 내에서 직접 정의될 수 있음
  • 독립 함수는 일반적으로 모듈화된 코드의 일부로 사용되며, 다른 함수나 객체에 의존하지 않고 자체적으로 작동
  • math.ts파일에 add라는 독립함수를 정의하고, main.ts 파일에서 math.ts 파일에 정의된 독립 함수를 임포트하여 사용할 수 있음

본론으로 들어가서,

  • 매개변수 타입에 타입이나 기본값을 지정하지 않으면 any 타입을 기본으로 갖음
  • 메서드를 호출하려면 허용 가능한 수의 인수가 필요
  • 재귀함수가 아니라면 대부분 반환 타입으로 유추 가능

클래스 생성자(constructor)는 매개변수와 관련하여 전형적인 클래스 메서드처럼 취급

생성자(constructor) ?

  • 타입스크립트에서 클래스 생성자(constructor)는 클래스의 인스턴스를 초기화하는 메서드
  • 클래스 생성자는 클래스 내부에 constructor 키워드로 정의
  • 생성자는 클래스로부터 객체를 만들 때 자동으로 호출되며, 인스턴스의 초기 상태를 설정하고 클래스 멤버 변수를 초기화하는 역할
1. 위의 예제에서 Person 클래스는 name과 age라는 두 개의 멤버 변수를 가지고 있음.
2. 생성자는 name과 age라는 두 개의 매개변수를 받아와서 클래스의 멤버 변수를 초기화.
3. 생성자 내부에서 this.name = name;과 this.age = age;와 같은 구문을 사용하여 매개변수의 값을 멤버 변수에 할당
4. 이후에 const person = new Person('John', 25);라는 코드를 통해 Person 클래스의 인스턴스를 생성
5. 생성자에 'John'과 25라는 값을 전달
6. 생성된 객체는 person.introduce()와 같은 메서드를 호출하여 자신의 멤버 변수 값을 사용

8.2 클래스 속성

  • 타입스크립트에서 클래스의 속성을 읽거나 쓰려면 클래스에 명시적으로 선언이 필요
  • 클래스 속성은 인터페이스와 동일한 구문을 사용해 선언
  • 클래스 속성 이름 뒤에 선택적으로 타입 애너테이션이 붙음
  • 타입스크립트는 생성자 내의 할당에 대해서 그 멤버가 클래스에 존재하는 멤버인지 추론하려 시도하지 않음 !
  • destination은 string으로 명시적으로 선언되어 있기 때문에 FieldTrip 클래스 인스턴스에 할당되고 접근이 가능
  • 클래스가 nonexistent 속성을 명시적으로 선언선언하지 않았기 때문에 생성자에서 this.nonexistent할당은 명시적으로 선언허용하지 않음

8.2.1 함수 속성

자바스크립트에서 클래스의 멤버를 호출 가능한 함수로 선언하는 구문 !

  1. 메서드 접근방식
  2. 함수인 속성을 선언하는 방식

🚫 주의할 점 !

  • myProperty의 형식 선언 부분에서 ()은 함수 형식을 나타내는데, 함수 형식을 나타내려면 파라미터와 반환 타입이 필요
  • 또 해당 오류는 클래스의 속성(myProperty)이 초기화되지 않았거나 생성자에서 할당되지 않았기 때문에 발생
  • 따라서, myProperty 속성을 초기화하기 위해 생성자에서 값을 할당해야 함!

  • GazeroPropertyParam 클래스는 매개변수 타입이 (input:boolean) => string인 takesParam 속성을 가짐

8.2.2 초기화 검사

  • 엄격한 컴파일러 설정이 활성화된 상태에서 타입스크립트는 undefined 타입으로 선언된 각 속성이 생성자에서 하당되었는지 확인
  • 엄격한 초기화 검사는 클래스 속성에 값을 할당하지 않는 실수를 예방할 수 있음

  • GazeroValue 클래스는 unused 속성에 값을 할당하지 않았으며, 이 경우 타입오류로 인식함


<참고: 위 예시는 엄격한 타입검사가 수행되어 타입오류를 표시한 상태임>

  • 엄격한 초기화 검사가 없다면, undefined 값에 접근할 수 없다고 하더라도 클래스 인스턴스는 undefined 값에 접근할 수 있음
  • 따라서 엄격한 초기화 검사가 수행되지 않으면 올바르게 컴파일되지만, 런타임시 문제가 발생

확실하게 할당된 속성

  • 의도적으로 할당하지 않는 경우
  • 엄격한 초기화 검사를 적용하면 안되는 속성 뒤에는 !를 추가해 검사를 비활성화 하게 함
  • 이 경우, undefined 값이 할당

8.2.3 선택적 속성

  • 선언된 속성 이름 뒤에 ?를 추가해 속성을 옵션으로 선언
  • |undefined를 포함하는 유니언 타입과 거의 동일하게 작동
  • 엄격한 초기화 검사는 생성자에서 선택적 속성을 명시적으로 설정하지 않아도 문제가 되지 않음

❓참고

8.2.4 읽기 전용 속성

  • 속성 이름 앞에 readonly 키워드를 추가해 속성을 읽기 전용으로 선언

  • readonly로 선언된 속성은 선언된 위치 또는 생성자에서 초깃값만 할당할 수 있음

  • 클래스 내의 메서드를 포함한 다른 모든 위치에서 속성을 읽을 수만 있고, 쓸 수 는 없음

  • 읽기 전용에는 값을 할당할 수 도 없고,

  • 객체안에 읽기전용으로 선언된 속성은 받아오지 않음

  • 클래스 속성은 처음에는 모두 문자열 리터럴로 선언되므로 둘 중 하나를 string으로 확장하기 위해서는 타입 애너테이션이 필요

즉, explicit의 타입은 string이라 생성자에서 다른 값을 할당할 수 있게되지만, implicit은 readonly속성에서 bye형식으로 선언되었기 때문에 생성자에서도 다른 값을 할당할 수 없음

🚫 주의

  • readonly 속성을 사용하면 무조건 값을 할당할 수 없음 !
  • readonly 속성을 사용하면, string으로 확장하기 위한 타입 애너테이션을 설정한 경우 생성자(constructor)에서 확장하기 위한 재할당이 가능함
console.log(quote.explicit);
//Ok

8.3 타입으로서의 클래스

  • 클래스 선언이 런타임 값과 타입 애너테이션에서 사용할 수 있는 타입을 모두 생성한다
  • Teacher 클래스의 이름은 teacher 변수에 주석을 다는 데 사용
  • teacher 변수에는 Teacher 클래스 자체 인스턴스처럼 Teacher 클래스에 할당할 수 있는 값만 할당해야 함

클래스의 동일한 멤버를 모두 포함하는 모든 객체 타입을 클래스에 할당할 수 있는 것으로 간주

  • withSchoolBus는 SchoolBus 타입의 매개변수를 받음
  • 매개변수로 SchoolBus 클래스 인스턴스처럼 타입이 () => string[]인 속성을 가진 모든 객체를 할당할 수 있음

8.4 클래스와 인터페이스

  • 클래스 이름 뒤에 implements 키워드와 인터페이스 이름을 추가함으로써 클래스의 해당 인스턴스가 인터페이스를 준수한다고 선언
  • 클래스를 각 인터페이스에 할당할 수 있어야 함을 타입스크립트에 나타냄
  • Student 클래스는 name 속성과 study 메서드를 포함해 Gazero 인터페이스를 올바르게 구현
  • Story에는 name, study가 누락되어 있어 타입 오류가 발생

8.4.1 다중 인터페이스 구현

  • 클래스에 구현된 인터페이스 목록은 인터페이스 이름 사이에 쉼표를 넣고, 개수 제한 없이 인터페이스를 사용할 수 있음
  • 클래스에서 Gazero를 구현 하려면 name 속성을 가져와야 하고, Garaded를 구현하려면 grade, Reporter를 구현하려면 report속성을 가져와야 함
  • Empty 클래스는 각각의 인터페이스 속성을 제대로 구현하지 못했으므로 세가지 타입 오류가 발생
  • AsNumber클래스, NotAsNumber클래스 모두 두 인터페이스를 제대로 구현하지 못하고 있음
  • 두 인터페이스가 매우 다른 객체 형태를 표현하는 경우에는 동일한 클래스로 구현하지 않아야 함 !

8.5 클래스 확장

  • 다른 클래스를 확장하거나 하위 클래스를 만드는 개념에 타입 검사를 추가
  • 기본 클래스에 선언된 메서드나 속성은 하위 클래스에서 사용 가능

8.5.1 할당 가능성 확장

  • 하위 클래스도 기본 클래스의 멤버를 상속
  • 기본 클래스의 인스턴스가 필요한 모든 곳에서 사용
  • 기본 클래스에 하위 클래스가 가지고 있는 모든 멤버가 없으면 더 구체적인 하위 클래스가 필요할 때 사용할 수 없음

  • Lesson 클래스가 기본 클래스, OnLine 클래스가 하위 클래스
  • 하위 클래스에서 기본 클래스의 멤버를 상속할 때 constructor에서 supuer(멤버, 멤버 ...)형태로 정의
  • 파생된 인스턴스는 기본 클래스 또는 하위 클래스를 충족하는 데 사용할 수 있음

❗ 다형성 !

  • 타입으로 상위 클래스를 지정하는 것은 하위 클래스의 인스턴스를 상위 클래스 타입으로 다룰 수 있음을 의미
  • 다형성을 활용한 것으로, 하위 클래스의 인스턴스(OnLine)를 상위 클래스 타입(Lesson)으로 할당
  • 상위 클래스인 Lesson은 하위 클래스인 OnLine 모든 기능을 갖고 있기 때문
  • 이렇게 하면 lesson 변수는 OnLine 인스턴스를 참조할 수 있으며, 해당 인스턴스의 속성과 메서드에 접근할 수 있음

  • 이는 Lesson 클래스의 인스턴스를 Online 타입인 online 변수에 할당하려고 시도하기 때문에 오류발생
  • 하위 클래스의 인스턴스를 상위 클래스 타입으로 다루는 것은 가능하지만, 상위 클래스의 인스턴스를 하위 클래스 타입으로 다루는 것은 허용되지 않음
  • 타입스크립트에서 하위 클래스의 인스턴스를 상위 클래스 타입에 할당하는 것은 가능
  • 인스턴스 할당(subClass = new LabeledPastGrades())을 통해 subClass 변수는 LabeledPastGrades의 인스턴스를 참조할 수 있음

8.5.2 재정의된 생성자

  • 자체 생성자가 없는 하위 클래스는 암묵적으로 기본 클래스의 생성자를 사용

  • 하위 클래스가 자체 생성자를 선언하면 super 키워드를 통해 기본 클래스 생성자를 호출

  • 하위 클래스 생성자는 모든 매개변수를 선언 가능

  • GradeAnnouncer의 생성자를 올바르게 호출하지 않으면 오류 발생

  • 자바스크립트에서 하위 클래스의 생성자 this 또는 super에 접근하기 전에 반드시 기본 클래스의 생성자 호출이 필수 !

  • 타입스크립트는 super()를 호출하기 전에 this 또는 super에 접근하려고 하면 타입 오류 발생

8.5.3 재정의된 메서드

  • 하위 클래스의 메서드가 기본 클래스의 메서드에 할당될 수 있는 한 하위 클래스는 기본클래스와 동일한 이름으로 새 메서드 선언 가능
  • 동일한 속성에 할당할 수 없음

8.5.6 재정의된 속성

  • 하위 클래서는 새 타입을 기본 클래스의 타입에 할당할 수 있는 한, 동일한 이름으로 기본 클래스 속성을 명시적으로 다시 선언할 수 있음
  • 재정의된 메서드와 마찬가지로 하위 클래스는 기본 클래스와 구조적으로 일치해야 함
  • 하위 클래스는 해당 속성을 더 구체적인 하위 집합으로 만들거나 기본 클래스 속성 타입에서 확장되는 타입으로 만듦

  • 속성의 유니언 타입의 허용된 값 집합을 확장할 수 없음
  • 확장한다면 하위 클래스 속성은 더 이상 기본 클래스 속성 타입에 할당할 수 없음

8.6 추상 클래스

  • 추상화하려는 클래스 이름과 메서드 앞에 abstract키워드를 추가
  • 추상화 기본 클래스에서 메서드의 본문을 제공하는 것을 건너뜀
  • 인터페이스와 동일한 방식으로 선언됨
  • School 클래스와 getStudentTypes 메서드는 abstract로 표시됨
  • 따라서 PreSchool, Absence는 getStudentTypes를 구현해야 함

추상클래스 직접 인스턴스화

  • 구현이 존재한다고 가정할 수 있는 일부 메서드에 대한 정의가 없으면 불가능
  • 추상클래스가 아닌 클래스만 인스턴스화 가능

8.7 멤버 접근성

  • 자바스크립트에서 클래스 멤버 이름 앞에 #을 추가해 private 클래스 멤버임을 표시
  • private 클래스 멤버는 해당 클래스 인스턴스에서만 접근 가능
  • 타입스크립트의 클래스 지원은 자바스크립트 # 프라이버시보다 먼저 만들어 졌음
  • 타입스크립트는 private 클래스 멤버를 지원함
  • 타입 시스템에만 존재하는 클래스 메서드와 속성에 대해 차이가 있을 수 있음
  • SubClass는 public, protected 멤버에만 접근이 가능

접근성 제한자와 readonly

  • 명시적 접근성 키워드를 먼저 적고 + readonly를 적어야 함

8.7.1 정적 필드 제한자

  • 타입스크립트는 static 키워드를 단독으로 사용하거나, readonly와 접근성 키워드를 먼저 작성하고, 그다음 static, readonly 키워드가 옴

  • static 클래스 필드에 대해 readonl용와 접근성 제한자를 사용하면,
  • 해당 필드가 해당 클래스 외부에서 접근되거나 수정되는 것을 제한하는 데 유용
profile
`나는 ${job} 개발자`

0개의 댓글