클래스

김동현·2022년 3월 22일
0

TypeScript

목록 보기
9/18
post-thumbnail

Class 정의

인스턴스 프로퍼티 정의

타입스크립트 클래스에서는 클래스 필드 정의를 통해 인스턴스 프로퍼티 이름과 프로퍼티 값의 타입을 명시해주어야 합니다.

즉, "프로퍼티이름: type"클래스 필드 형식으로 인스턴스 프로퍼티 이름과 값의 타입을 명시해주어야 합니다.

옵셔널 인스턴스 프로퍼티

옵셔널 프로퍼티를 사용하기 위해서 ?을 사용할 수도 있습니다.

즉, "프로퍼티이름?: 타입"로 옵셔널 프로퍼티를 정의할 수 있습니다.

클래스 이름을 타입으로 사용

타입스크립트에서 class 이름은 "타입과 값으로 모두 사용"할 수 있습니다.

클래스 이름인 Person을 타입처럼 사용할 수 있으며, Person 타입은 Person 클래스가 생성하는 인스턴스의 구조를 갖는 객체 타입을 의미하게 됩니다.

즉, Person 타입은 { name: string; age: number } 타입을 의미합니다.

추가적으로 프로토타입 메서드의 경우에는 프로토타입 체인상에 존재해야 합니다. 즉, 상속을 받거나 직접 정의되어야 합니다.

매개변수 속성

만약 인스턴스 프로퍼티 이름과 constructor 매개변수의 이름이 서로 일치하는 경우에는 따로 클래스 필드 정의로 명시할 필요 없이 constructor 메서드의 매개변수 이름 앞에 "접근 지정자(public, protected, private)"를 작성하여 인스턴스 프로퍼티 타입을 명시할 수 있습니다.

위 코드처럼 인스턴스 프로퍼티에 대한 타입을 클래스 필드 정의로 따로 작성하지 않고 constructor 메서드의 매개변수 앞에 접근 지정자를 작성할 수 있습니다.

프로토타입 메서드 정의

기존 자바스크립트에서는 클래스 내부에 정의한 메서드는 기본적으로 프로토타입의 메서드가 됩니다. 이때 프로토타입 메서드 내부 this 바인딩될 객체가 타입스크립트가 자동적으로 추론해줍니다.

클래스 내 정의한 프로토타입 메서드의 경우 클래스가 생성할 인스턴스의 구조를 갖는 객체 타입으로 추론됩니다.

메서드는 객체에 포함된 것이 아니라 독립적으로 존재하는 객체이며 프로퍼티가 단지 함수 객체를 가리키고 있을 뿐입니다. 그러므로 해당 메서드를 다른 객체로 호출하거나 일반 함수로 호출하면 내부 this 바인딩이 달라지게 됩니다.

위 코드에서 프로토타입 메서드 내 this는 생성될 인스턴스의 타입을 갖도록 타입이 자동적으로 추론되어 사용 가능한 API가 보여지며, 이외 접근하는 경우 에러가 발생하게 됩니다.

정적 프로퍼티 / 메서드 정의

정적 메서드와 정적 프로퍼티는 클래스 객체 자체가 갖는 메서드와 프로퍼티입니다. static 키워드를 사용하여 메서드와 프로퍼티 정의하면 해당 메서드와 프로퍼티는 정적 메서드, 정적 프로퍼티로서 생성됩니다.

static 키워드는 프로퍼티의 경우 클래스 필드 정의에 작성하고, 메서드의 경우 메서드 이름 앞에 작성해줍니다.

정적 프로퍼티인 className과 정적 메서드인 showInfo는 MyClass 클래스가 평가되어 생성되는 객체의 프로퍼티와 메서드로 추가됩니다.

즉, className과 showInfo는 클래스 객체로만 접근이 가능하며 이외 프로토타입이나 인스턴스로는 접근이 불가능합니다. 접근시 타입스크립트에서 에러를 표시하게 됩니다.

접근자 프로퍼티 정의

접근자 프로퍼티란 다른 데이터 프로퍼티 값에 접근하거나 다른 동작을 위한 접근자 함수 getter와 setter를 의미합니다.

메서드 이름 앞에 get, set 키워드를 작성하여 접근자 프로퍼티를 정의할 수 있습니다.

get 접근자 프로퍼티는 반드시 무언가 반환해야 하며, set 접근자 프로퍼티는 하나의 매개변수를 정의해야 합니다. 이 또한 타입스크립트 접근자 프로퍼티 형태를 강제하도록 합니다.

참고로 접근자 프로퍼티는 메서드 형태로 정의하기 때문에 readonly 키워드로 읽기 전용 프로퍼티로 작성하는 것이 불가능합니다.

추상 클래스

타입스크립트에서 추상 클래스를 통해 상위 클래스를 정의할 수 있습니다.

추상 클래스는 abstract 키워드를 사용하며, 인스턴스 생성이 불가능합니다. 단지 상속을 위한 상위 클래스로만 사용됩니다.

추상 프로퍼티

추상 클래스 내에서는 추상 프로퍼티를 작성할 수 있습니다. 추상 프로퍼티는 클래스 필드 정의 앞에 abstract 키워드를 작성해줍니다.

추상 프로퍼티는 단지 클래스 필드로 프로퍼티 이름과 타입만 정의합니다. 즉, 따로 초기화를 하지 않습니다.

이후 추상 클래스를 상속받는 하위 클래스에서 반드시 재정의가 되어야 합니다.

참고로 추상 프로퍼티를 옵셔널 프로퍼티로 정의하더라도 반드시 하위 클래스에서 재정의 해주어야 하며, 하위 클래스에서는 옵셔널 프로퍼티로 정의하지 않아도 에러는 발생하지 않습니다.

추상 메서드

추상 클래스 내 추상 메서드를 정의하기 위해서는 메서드 이름 앞에 abstract 키워드를 작성해줍니다.

추상 메서드는 메서드 이름, 매개변수 개수, 매개변수 타입, 반환값 타입만을 작성합니다. 즉, 메서드 몸체는 작성하지 않고 메서드 구조, 형태에 대해서만 정의하고 하위 클래스에서 이를 동일한 이름으로 반드시 재정의 해주어야 합니다.

참고로 추상 프로퍼티나 추상 메서드는 static 키워드와 함께 작성할 수 없으며, private 접근 지정자도 함께 사용할 수 없습니다.

접근 지정자

타입스크립트로 클래스를 정의할 때 인스턴스 프로퍼티가 할당받을 값에 대한 타입을 클래스 내부에 작성해야된다는 것을 위에서 살펴보았습니다.

클래스 필드로 인스턴스 프로퍼티에 대한 타입을 지정할 때 해당 "프로퍼티의 접근 지정자"도 함께 작성할 수 있습니다. 접근 지정자는 가장 앞에 작성해주어야 합니다.

기본적으로 모든 인스턴스 프로퍼티는 public으로 동작하며 클래스 외부에서도 접근이 가능합니다. 즉, 생성되는 인스턴스의 name 프로퍼티의 경우 외부에서 접근 가능한 프로퍼티가 됩니다.

반면에 age 프로퍼티의 경우 private으로 지정하여 클래스 내부에서만 접근이 가능한 프로퍼티가 됩니다.


메서드의 경우 메서드 가장 선두에 접근 지정자를 작성할 수 있습니다.

읽기 전용 프로퍼티

프로퍼티에 readonly를 작성하면 해당 프로퍼티는 읽기 전용 프로퍼티로서 초기화된 값 읽기만 가능하며 이후 값을 변경할 수 없습니다.

참고로 메서드에는 readonly 지정할 수 없습니다.

위 코드처럼 role 프로퍼티에 readonly를 작성하여 읽기 전용 프로프터로 지정했습니다. 이후 프로퍼티에 값을 재할당할 수 없습니다.

readonly 키워드는 클래스 필드 정의 혹은 constructor 메서드의 매개변수에 작성 가능합니다.

키워드 작성 순서

접근 지정자, readonly, get/set, abstract, static 키워드를 작성하는 순서는 아래와 같습니다.

  1. 접근 지정자는 "가장 앞"에 작성됩니다. 모든 프로퍼티와 메서드에 사용할 수 있습니다. 기본적으로 public으로 지정되어 있으며 명시적으로 private, protected로 지정할 수 있습니다.

  2. readonly와 get/set 키워드는 "가장 뒤"에 작성됩니다. readonly는 프로퍼티에만 적용할 수 있습니다. 즉, readonly와 get/set은 함께 작성 불가능합니다.

  3. abstract와 static은 접근 지정자 뒤 readonly와 get/set 키워드 앞에 작성됩니다. abstract와 static은 같이 사용할 수 없습니다. 또한 private와 abstract도 함께 사용할 수 없습니다.

싱클톤 패턴

객체 지향 프로그래밍에 싱글톤 패턴이라는 개념이 존재합니다. 싱글톤 패턴이란 특정 클래스를 통해 단 하나의 인스턴스만을 생성하도록 하는 개념입니다.
이 패턴은 정적 메서드나 프로퍼티를 사용할 수 없으며 여러 인스턴스도 생성할 수 없고 오직 클래스를 기반으로 단 하나의 인스턴스만을 생성하고자 하는 경우에 유용하게 사용됩니다.

싱글톤 패턴을 사용하기 위해서는 클래스의 constructor 메서드 앞에 private 키워드를 작성하여 정의합니다.

그리고 클래스 내부에 정적 메서드를 정의하고 정적 메서드 내부에서는 해당 클래스로 생성한 인스턴스가 존재하는지 검사하고 없다면 새롭게 생성하는 로직을 작성합니다. 이를 구현하기 위해서 private 정적 프로퍼티를 해당 클래스 타입으로 정의해줍니다.

정적 메서드 내부에서는 private 정적 프로퍼티에 인스턴스가 존재하는지 확인하고 있다면 존재하는 인스턴스를 반환하고, 없다면 새로운 인스턴스를 생성하여 반환하도록 작성합니다. 즉, new 연산자와 함께 클래스를 생성하는 것이 아니라 정적 메서드를 호출하여 인스턴스를 생성하고 접근하도록 합니다.

instance와 instance2는 둘 다 동일한 객체의 참조값 갖고 있습니다.

profile
Frontend Dev

0개의 댓글