객체 지향 프로그래밍? ⇒ 코드에서 실제와 유사한 객체를 만듦
- 클래스
⇒ 객체의 청사진
⇒ 객체가 가지는 프로퍼티나 메서드 등의 구조를 정의
- 객체(인스턴스)
⇒ 애플리케이션의 로직을 분할해 객체로 각 로직을 관리할 수 있음
⇒ 데이터를 저장하고 메서드를 실행하는데 사용하는 자료구조
⇒ 하나의 클래스를 기반으로 동일한 구조를 가짐
⇒ 1클래스 당 n객체 생성 가능
- JS의 클래스 ⇒ 생성자 함수의 문법 설탕..
- 속성(like 변수), 생성자, 메서드(like 함수)
- 속성이나 메서드에 const, let을 써주지 않아도 됨
- 속성, 메서드에 타입을 각각 써주면 됨
- 속성의 초기화는 필수가 아님
- constructor : 생성자 함수, 객체가 생성될 때 사용
- 메서드는 콜론과 function 키워드를 생략 가능(JS 규칙)
- 클래스의 메서드가 js에서는 prototype안에 메서드로 정의되어 컴파일 된다
- es6 미만에는 클래스라는 개념이 없어서 생성자 함수로 컴파일 됨
- es6에는 클래스가 있긴 하지만 필드가 없다. 따라서 필드 없는 클래스로 컴파일 됨
- 특정한 객체의 메서드를 어떤 변수의 값으로 할당하면 해당 메서드를 가리키게 된다.
- 메서드(혹은 함수)의 첫번째 매개변수로 this를 넣고 이 this의 타입을 명시해줄 수 있다.
- 해당 객체만 이 메서드를 호출할 수 있음
- 함수 호출시 this 매개변수는 안써줘도 된다.
- 메서드가 아닌 일반 함수(화살표 함수는 안됨)에서 이렇게 명시함으로써 함수 내에 this를 타입을 any가 아닌 특정하게 지정해줄 수 있다
- private, public으로 접근 제어자를 지정할 수 있다
- public: (기본) 외부에서 접근 가능
- private: 외부에서 접근 불가능(자식도 불가)
- +) protected: (for 상속)외부에서 접근 불가능(자식은 가능)
- 이 접근제어자 개념은 es6에서 생긴 것으로, 그 이전 js에서는 xx
- 따라서 TS의 js 버전을 es6미만으로 한다면 해당 개념은 컴파일 되지 않고, ts에서 컴파일 오류가 난다고 해도 런타임 오류는 나지 않는다
- 생성자 인수에 접근 제어자를 명시해서, 객체 생성 시 받은 인수로 필드를 바로 생성 가능
- 여기선 public이라도 명시해줘야 함에 주의
- readonly로 속성을 읽기 전용, 즉 초기화 후에 변화하지 못하게 할 수 있다
- ts에만 있는 개념
- 상속
- 클래스 이름 뒤에
extends 부모클래스
를 덧붙이면 해당 부모 클래스를 상속 한다는 의미 - 내부 코드가 없다면 걍 Department와 동일한 기능의 클래스가 됨
- 한 클래스만 상속 가능하다
- 자식 클래스의 생성자 함수를 따로 만들어 주려면, 생성자 내부에 부모 클래스의 생성자를 무조건 먼저 불러줘야 함
- 부모 생성자 부르기:
super()
⇒ 매개변수도 부모 생성자와 같아야 함 - 물론 자식 생성자에서도 기존 개념(접근 제어자로 새 변수 선언 등)이 적용된다
- 메서드를 오버라이드, 즉 재정의 할 수 있다
- 추상 클래스
- 메서드의 오버라이드를 강제하는 것
- 기본 클래스에서 메서드를 구현x(중괄호 없이 선언), 상속받은 자식 클래스들에서 구현을 미룸
- 기본 클래스의 메서드는 매개변수와 반환값의 타입은 명시
- 자식 클래스들에서는 무조건 해당 메서드를 구현해야한다
- 추상화 하고 싶은 메서드 앞에
abstract
를 붙임. 클래스 내에 하나라도 abstract가 있으면 클래스 이름 앞에도abstract
를 붙여야 함 ⇒ 해당 클래스는 추상클래스가 됨 - 추상 클래스는 상속 받기 위해서만 존재하는 클래스이고, 인스턴스화 할 수 없다
⇒ 기존에 있던 클래스의 필드-생성자-메서드를 다 받는 것, 여기에 추가도 가능하다
- getter, setter
- 외부에서 필드 값을 얻게하는 get, 외부에서 필드 값을 정의하게 하는 set
get 게터이름() { return ~ }
set 세터이름(name: string) { ~ }
- 외부에서 호출:
객체.세터이름 = ‘name’
- 외부에서 부를 때 메서드가 아닌 속성처럼 접근
객체.게터이름
,객체.세터이름
- 그래서 외부에선 속성에 바로 접근하는 것 처럼 보임 ㅎ
- 정적 메서드 & 속성
static
을 변수나 메서드 이름 앞에 붙여주면 정적 변수/메서드가 됨- 생성자를 포함한 정적 메서드가 아닌 곳에서는 this로 정적 메서드, 속성에 접근할 수 없다
- 정적 메서드가 아닌 곳에서의 this는 인스턴스를 가리키는 것이기 때문
- 대신 클래스 명으로는 접근 가능
- 정적 메서드에서 this는 클래스이다
: 인스턴스에선 접근 불가하고, 클래스에서 직접 접근가능하다
- 싱글톤 패턴
- 클래스당 하나의 인스턴스만 있는 것
- 생성자를 private으로 막아서 외부에서 인스턴스를 여러개 생성하지 못하도록 함
- 대신 클래스내에 인스턴스를 미리 선언함. 반환 값은 해당 클래스
- 그리고 인스턴스를 반환하는 메서드를 public으로 선언해 해당 메서드에서만 인스턴스를 가져오도록 함
- 해당 인스턴스에서는 지금 클래스에 선언된 인스턴스가 초기화(생성자로 정의됨)가 되었는지 확인
- 초기화가 안되어 있으면 생성자로 인스턴스를 생성해줌
- 되어 있으면 기존의 인스턴스를 생성함
- 인스턴스 반환 메서드는 static으로 선언해서, 외부에서 인스턴스로 접근하지 않고 클래스로 접근하게 한다(어차피 생성자로 인스턴스 생성불가라 인스턴스로 접근 못함)
- 클래스에 선언된 인스턴스를 여기서 반환할것이라, 해당 인스턴스도 static이어야 한다