-
Typescript(3) - 클래스 패턴웹 개발/typescript 2023. 6. 4. 13:16
클래스 상속
- 클래스 상속에 extends 키워드를 사용하여 수퍼 클래스의 속성을 그대로 상속받아올 수 있다.
- 오버라이딩 : 자바에서도 자주 나오는 문법 형태로, 부모 클래스(수퍼 클래스)로부터 상속받아온 속성을 다른 값으로 덮어쓰는 것을 의미한다.
- 클래스 > 메서드, 속성, 인스턴스 > 함수> 클래스 안에서 정의된 속성을 가져와서 사용
가장 기초적인 상속 형태
// Book 수퍼 클래스를 상속 받은 E_Book 클래스 class E_Book extends Book { // paper_type 오버라이딩 paper_type = '스크린'; }
constructor & super
- 수퍼 클래스를 상속받은 서브 클래스는 수퍼 클래스의 기능에 더하여 좀 더 많은 기능을 갖도록 설계하는 것이 자식 컴포넌트에서 부모를 상속받는 이유이다.
- 따라서 기존 부모의 속성 + 부모 속성 수정 + 새로운 속성 추가 = 자식 클래스(서브 클래스)라고 생각하면 된다.
- constructor
- 상속 받은 부모 클래스의 생성자를 서브 클래스의 생성자로 덮어쓸 수 있도록 함
- 즉 부모의 물려받은 속성을 서브 클래스의 consructor로 그대로 쓰는 것과 동시에 수정이 가능하다.
- super()
- 수퍼 클래스의 생성자에 요구되는 인자를 전달해야 한다.
- 기본 클래스 호출시 사용된다.
- 생성자에서 this 사용 전에 호출되어야 한다.
- this.name은 name이라고 생각하면 되고, 파생클래스에서 인자를 전달할 때 사용한다.
- 수퍼 클래스 constructor를 덮어쓰기 위해서는 super() 실행이 필요함
// 기본 클래스 class Actor { name: string constructor(name: string) { this.name = name; } actorName() { return `배우의 이름은 ${this.name}`; } } // 파생 클래스 class Person extends Actor { constructor(name: string) { super(name); } personName() { return `${super.actorName()} 사람의 이름은 ${this.name}`; } } const person = new Person('Jongseok'); console.log(person.personName());
1. 매개 변수로 Jonseok을 넣는다.
- 즉, person이라는 변수 안에 Person클래스(파생클래스)안으로 Jonseok이 들어감. 이때 파생클래스는 부모 클래스의 내용을 상속을 받았을 뿐이지, 외부 클래스이므로 바로 접근이 가능하다.
2. 파생 class의 생성자 함수(constructor)로 Jongseok이 들어간다.
class Person extends Actor { constructor(name: string) { super(name); }
3. 생성자 함수에서 상위의 기본 클래스인 name으로 Jongseok이 들어가게 된다. 즉, super은 자식 클래스에서 부모 클래스로 연결해주는 징검다리 같은 친구라고 생각하면 됨!
super(name);
4. 기본 클래스의 name으로 들어가게 된다.
- 수퍼 클래스의 protected 속성은 서브 클래스에서 접근 가능한 반면, private속성은 접근이 불가능하다.
class E_Book extends Book { constructor( title:string, author:string, pages:number, public is_downloadable:boolean ){ super(title, author, pages); this.is_downloadable = is_downloadable; // 수퍼 클래스의 protected 속성은 접근 가능 console.log(this.paper_type); // 수퍼 클래스의 private 속성은 접근 불가능 // [오류] // [ts] '_manufacturing_plant' 속성은 private이며 'Book' 클래스 내에서만 액세스할 수 있습니다. // (property) Book._manufacturing_plant: string console.log(this._manufacturing_plant); } }
getter & setter
- 비공개로 설정할 필요가 있는 속성을 private로 설정한 후, 이 속성에 접근하여 값을 읽거나, 쓰기 위한 Getter, Setter 함수를 사용하여 속성을 정의할 수 있다.
- getter : 멤버 변수의 값을 호출함
get 속성이름() { return this.속성이름 }
- setter : 멤버 변수의 값을 설정(수정)함
set 속성함수(매개변수 : 매개변수타입){ ... this.위의속성 = 매개변수; }
class Plant { // 비공개 속성 '종(Species)' private _species:string|null = null; // getter 함수 // private 속성에 함수 내부에서 접근하여 사용할 수 있도록 함 get species(): string { return this._species; } // setter 함수 // getter와 항상 붙어다니는 친구로 getter에서 접근하여 private 속성을 상속받아 사용할 수 있도록 함 set species(value:string) { if ( value.length > 3 ) { this._species = value; } } } /* 인스턴스 생성 ------------------------------------------------ */ let plant = new Plant(); console.log(plant.species); // null plant.species = '줄기'; console.log(plant.species); // null plant.species = '푸른 식물'; console.log(plant.species); // '푸른 식물'
스태틱 속성/메서드
- 클래스를 통해 인스턴스를 생성할 필요 없이, 클래스의 속성 또는 메서드를 사용할 때 사용함
class Mathmatics { // 스태틱 속성 static PI:number = Math.PI; // 스태틱 메서드 // circumference = 둘레(원주) static calcCircumference(radius:number) :number { return this.PI * radius * 2; } // 스태틱 메서드 static calcCircleWidth(radius:number): number { return this.PI * Math.pow(radius, 2); } } // radius = 반지름 let radius = 4; console.log('PI(원주율) = ', Mathmatics.PI); console.log(`반지름이 ${radius}인 원의 넓이: πr² = `, Mathmatics.calcCircleWidth(radius)); //함수.메서드(속성); console.log(`반지름이 ${radius}인 원의 둘레: 2πr = `, Mathmatics.calcCircumference(radius));
추상클래스
- class 앞에 abstract라고 표기(추상메서드도 마찬가지임)
- 추상 메소드는 정의만 있을 뿐 몸체(body)가 구현되어 있지 않다(추상클래스 ). 몸체는 추상 클래스를 상속하는 클래스에서 해당 추상 메소드를 통해 필히 구현해야 한다.
- 추상 클래스는 추상 메서드 뿐만 아니라, 실 사용이 가능한 메서드도 정의하는 것이 가능하다. 추상 클래스를 상속하는 클래스를 통해 생성된 인스턴스는 이 메서드를 사용할 수 있는 것이 가능하나, 추상 클래스는 말 그대로 추상이므로 클래스와 달리 인스턴스를 생성하지 않는다.
// 추상 클래스 abstract class Project { public project_name:string|null = null; private budget:number = 2000000000; // 예산 // 추상 메서드 정의 // 몸체를 직접 구현하는 것은 불가능하다. (추상 클래스 내에서 구현된 메서드로 이 추상 메서드의 몸체를 구현해야됨) public abstract changeProjectName(name:string): void; // 실제 메서드 정의(추상 클래스에서 실사용하는 메서드를 정의하는 것이 가능하다.) public calcBudget(): number { return this.budget * 2; } } // [오류] // [ts] 추상 클래스의 인스턴스를 만들 수 없습니다. // constructor Project(): Project let new_project = new Project(); //이거 오류뜸 : 추상 클래스의 인스턴스를 만들어서 매개변수를 집어넣는 것은 불가능하다.
- 몸체는 추상 클래스를 상속하는 클래스에서 해당 추상 메소드를 통해 반드시 구현해야 한다.
- 즉, Project 추상 클래스를 상속 받은 WebProject 클래스는 추상 클래스 내에 정의된 추상 메서드를 반드시 구현해야 한다.
// 클래스 ⟸ 추상 클래스 상속 // 반드시 Projec에서 구현한 추상메서드를 WebProject 안에서 구현해야 한다. class WebProject extends Project { // [오류] // [ts] 비추상 클래스 'WebProject'은(는) 'Project' 클래스에서 상속된 // 추상 멤버 'changeProjectName'을(를) 구현하지 않습니다. (오류 발생) // class WebProject }
- 추상 클래스를 상속하는 클래스는 추상 클래스에 정의된 메서드를 구현한 예시
- 추상클래스를 상속하는 일반 클래스는 일반적인 클래스이기 때문에 인스턴스를 생성하는 것이 가능하다.
class WebProject extends Project { // 위의 추상 클래스에 정의된 추상 메서드 구현 changeProjectName(name:string): void { this.project_name = name; } } /* 인스턴스 생성 ------------------------------------------------ */ let new_project = new WebProject(); console.log(new_project.project_name); // null new_project.changeProjectName('CJ 올리브 네트웍스 웹사이트 개편'); console.log(new_project.project_name); // 'CJ 올리브 네트웍스 웹사이트 개편'
싱글턴
- private 접근 제어자를 사용해 constructor() 앞에 붙이면 new 키워드를 통해 인스턴스를 생성하지 못하도록 제한할 수 있다. 하지만 이 과정은 굉장히 복잡하고, 코드를 낭비하기 때문에 타입스크립트에서는 특이한 스태틱 매서드를 통해서 인스턴스 구현 횟수를 제한해 놓았음
- getInstance() : 오직 한 번만 인스턴스를 생성할 수 있도록 인스턴스 횟수를 제한한 스태틱 메서드이며, 싱글턴 패턴 구현의 핵심이다.
class OnlyOne { private static instance: OnlyOne; public name:string; // new 클래스 구문 사용 제한을 목적으로 // constructor() 함수 앞에 private 접근 제어자 추가 private constructor(name:string) { this.name = name; } // 오직 getInstance() 스태틱 메서드를 통해서만 // 단 하나의 객체를 생성할 수 있습니다. public static getInstance() { if (!OnlyOne.instance) { OnlyOne.instance = new OnlyOne('싱글턴 객체'); } return OnlyOne.instance; } } /* 인스턴스 생성 ------------------------------------------------ */ // [오류] // [ts] 'OnlyOne' 클래스의 생성자는 private이며 클래스 선언 내에서만 액세스할 수 있습니다. // constructor OnlyOne(name: string): OnlyOne let bad_case = new OnlyOne('오류 발생'); let good_case = OnlyOne.getInstance();
읽기전용 속성(ReadOnly)
-
'웹 개발 > typescript' 카테고리의 다른 글
typescript(5) - 인터페이스 (0) 2023.06.25 typescript(3) - 모듈 , 네임스페이스 (0) 2023.06.25 타입스크립트(2) - ES6, 클래스 함수(1) (0) 2023.05.31 Typescript(1) - 설치와 시작 (0) 2023.05.24