일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |
- Cookie
- 방송대컴퓨터과학과
- MySQL
- aws
- 프로그래머스
- TiL
- 엘리스sw트랙
- CSS
- 항해99
- 방송대
- 자격증
- 코딩테스트준비
- 데이터베이스시스템
- JavaScript
- 코딩테스트
- 유노코딩
- Python
- nestjs
- HTML
- 코드잇
- node.js
- 꿀단집
- 개발자취업
- 중간이들
- 99클럽
- redis
- 파이썬
- SQL
- 파이썬프로그래밍기초
- Git
- Today
- Total
배꼽파지 않도록 잘 개발해요
[엘리스sw] 5주차 3일 - 타입스크립트 개념, 클래스 본문
◆ TypeScript 기본
◆ Class
타입스크립트 개념
타입스크립트 개요
타입스크립트
· Microsoft에서 개발한 오픈 소스 언어
· 자바스크립트에 JavaScript에 정적 타이핑을 추가한 언어로, 자바스크립트의 최상위 집합
· 자바스크립트로 변환해주는 컴파일러가 필요함.
타입스크립트를 사용하는 이유
· 동적 타입을 정적으로 선언할 수 있음.
· 타입 유추를 통한 타입 제어가 가능함.
· 자바스크립트의 런타임 단계에서 발생하는 타입 에러는 타입스크립트를 이용한다면 컴파일 단계에서 미리 확인하고 고칠 수 있음.
· JavaScript에서 찾을 수 없는 추가 코드 기능을 제공함.
자바스크립트
let a;
a = 1;
a = '1';
console.log(a) // 1
const sum = (a, b) => {
return a + b;
}
console.log(sum(1, "2")); // 12
타입스크립트
let a : number;
a = 1;
a = '1';
// main.ts(4,1): error TS2322: Type 'string' is not assignable to type 'number'.
const sum = (a: number, b: number) => {
return a + b;
}
console.log(sum(1, 2)); // 3
타입스크립트에서는 매개변수 타입을 제어할 수 있어서 함수 아규먼트로 숫자를 전달하면 결과값으로 숫자를 전달받을 수 있다는 것을 명시할 수 있음.
TypeScript의 기본 Type
TypeScript는 JavaScript의 코드에 변수나 함수 등 Type을 정의할 수 있음.
Type을 나타내기 위해서 Type Annotation(타입 표기)를 사용한다.
TypeScript의 Type
- 기본 자료형(primitive type) : string, boolean, number, null, undefined, symbol(ES6 추가)
- 참조 자료형(reference type) : object, array, function
- 추가 제공 자료형 : tuple, enum, any, void, never
기본 자료형 (primitive type)
- object와 reference 형태가 아닌 실제 값을 저장하는 자료형
- primitive type 내장 함수를 사용할 수 있는 것은 자바스크립트 처리 방식 덕분임
string
let str: string = "hello!";
Boolean
let isTrue: boolean = true;
number
부동 소수값을 저장하는 타입
2진수, 8진수, 10진수, 16진수 사용 가능
let decimal: number = 6;
let hex: number = 0xf00d;
let binary: number = 0b1010;
let octal: number = 0o744;
null
값이 의도적으로 비어 있는 상태
let n: null = null;
undefined
어떤 값도 할당되지 않은 상태
let u: undefined = undefined;
console.log(null === undefined) // false
console.log(null == undefined) // true
console.log(null === null) // true
console.log(null == null) // true
console.log(!null) // true
console.log(isNaN(1 + null)) // false
console.log(isNaN(1 + undefined)) // true
main.ts(6,19): error TS2365: Operator '+' cannot be applied to types '1' and 'null'.
main.ts(7,19): error TS2365: Operator '+' cannot be applied to types '1' and 'undefined'.
typeof로 데이터타입 확인
typeof null // 'object'
typeof undefined // 'undefined'
참조 자료형(reference type)
- 객체, 배열, 함수 등과 같은 Object 형식의 타입
- 메모리에 값을 주소로 저장하고, 출력 시 메모리 주소와 일치하는 값을 출력
object
기본 자료형에 해당하지 않는 타입
string, boolean, number, null, undefined를 제외한 타입
function create(o: object): void{}
create({prop: 0}) // 성공
create([1, 2, 3]) // 성공
create("string") // error
create(false) // error
create(42) // error
create(null) // error
create(undefined) // error
array
배열을 저장하는 타입
let arr: number[] = [1, 2, 3]
// 아래와 같이 제네릭을 사용한 타입 표기 가능
let arr: Array<number> = [1, 2, 3]
추가 제공 자료형
- TypeScript에서 개발자의 편의를 위해 추가로 제공하는 타입
tuple
길이와 각 요소의 타입이 정해진 배열을 저장하는 타입
let arr: [string, number] = ["Hi", 6];
// 문자열에 쓰는 메소드 concat을 호출함
arr[1].concat("!");
// Property 'concat' does not exist on type 'number'.
// 정의하지 않은 index 호출 시 오류
arr[3] = 'hello';
// Tuple type '[string, number]' of length '2' has no element at index '3'.
enum
특정 값(상수)들의 집합을 저장하는 타입
enum Car {BUS, TAXI, SUV};
let bus: Car = Car.BUS;
let bus: Car = Car[0]; // 인덱스 번호로 접근
// 인덱스를 사용자 편의로 변경
enum Car { BUS = 1, TAXI = 2, SUV = 3 };
let taxi: String = Car[2];
enum Car { BUS = 2, TAXI, SUV };
let taxi: String = Car[3];
any
모든 타입을 저장 가능
컴파일 중 타입 검사를 하지 않음
let str: any = "hi";
let num: any = 10;
let arr: any = ["a", 2, true];
void
보통 함수에서 반환값이 없을 때, any의 반대 타입
변수에는 undefined와 null만 할당하고, 함수에는 반환값을 설정할 수 없는 타입
let unknown: void = undefined;
function sayHi(): void{
console.log("hi");
}
never
발생할 수 없는 타입
- 항상 오류를 발생시키거나 절대 반환하지 않는 반환 타입
- 종료되지 않는 함수
// 종료되지 않는 함수
function neverEnd(): never {
while(true) {}
}
// 항상 오류를 발생시키는 함수
function error(message: string): never {
throw new Error(message);
}
Utility types
Utility types
· TypeScript는 공통 타입 변환을 용이하게 하기 위해 유틸리티 타입을 제공한다.
· 유틸리티 타입은 전역으로 사용 가능하다.
종류
- Partial<T>, Readonly<T>
- Record<K, T>, Pick<T,K>
- Omit<T,K>, Exclude<T,U>, Extract<T,U>
- NonNullable<T>, Parameters<T>, ConstructorParameters<T>
- ReturnType<T>, Required<T>
Partial<T>
프로퍼티를 선택적으로 만드는 타입을 구성
주어진 타입의 모든 하위 타입 집합을 나타내는 타입을 반환
type PartialPerson = Partial<{ name: string; age: number }>;
const partialPerson1: PartialPerson = {};
const partialPerson2: PartialPerson = { name: 'John' };
const partialPerson3: PartialPerson = { age: 25 };
const partialPerson4: PartialPerson = { name: 'Jane', age: 30 };
위 네 가지 경우는 다 유효함.
Readonly<T>
프로퍼티를 읽기 전용(readonly)으로 설정한 타입 구성
type ReadonlyPerson = Readonly<{ name: string; age: number }>;
const readonlyPerson: ReadonlyPerson = { name: "John", age: 25 };
readonlyPerson.name = "Jane"; // 에러 (수정 불가)
Record<K,T>
프로퍼티 집합 K로 타입을 구성한다.
타입의 프로퍼티들을 다른 타입에 매핑시키는 데 사용한다.
type Person = { name: string; age: number };
type PersonRecord = Record<string, Person>;
const personRecord: PersonRecord = {
john: { name: "John", age: 25 },
jane: { name: "Jane", age: 30 },
};
레코드는 키-값 쌍이며, Record<string, Person>은 키가 문자열이고 값이 Person 유형인 레코드
Pick<T,K>
프로퍼티 K의 집합을 선택해 타입을 구성한다.
type Person = { name: string; age: number; address: string };
type PersonSubset = Pick<Person, "name" | "age">;
const personSubset: PersonSubset = { name: "John", age: 25 };
// personSubset는 선택한 속성만 포함
Omit<T,K>
모든 프로퍼티를 선택한 다음 K를 제거한 타입을 구성한다.
type Person = { name: string; age: number; address: string };
type PersonWithoutAddress = Omit<Person, "address">;
const personWithoutAddress: PersonWithoutAddress = { name: "John", age: 25 };
// personWithoutAddress는 "address" 속성이 없음.
Exclude<T,U>
T에서 U에 할당할 수 있는 모든 속성을 제외한 타입을 구성한다.
type Numbers = 1 | 2 | 3 | 4;
type EvenNumbers = Exclude<Numbers, 1 | 3>;
const evenNumbers: EvenNumbers = 2 | 4;
// evenNumbers에는 짝수만 포함
Extract<T,U>
T에서 U에 할당할 수 있는 모든 속성을 추출하여 타입을 구성한다.
type Numbers = 1 | 2 | 3 | 4;
type OddNumbers = Extract<Numbers, 1 | 3>;
const oddNumbers: OddNumbers = 1 | 3;
// oddNumbers에는 홀수만 포함
NonNullable<T>
null과 undefined를 제외한 타입
type NullableString = string | null | undefined;
type NonNullString = NonNullable<NullableString>;
const nonNullString: NonNullString = "Hello";
// nonNullString은 null 또는 undefined일 수 없음.
Parameters<T>
함수 타입 T의 매개변수 타입들의 튜플 타입을 구성한다.
type AddFunction = (a: number, b: number) => number;
type AddFunctionParameters = Parameters<AddFunction>;
const addFunctionParams: AddFunctionParameters = [1, 2];
// addFunctionParams는 두 개의 숫자로 이루어진 튜플
ConstructorParameters<T>
생성자 함수 타입의 모든 매개변수 타입을 추출한다.
모든 매개변수 타입을 가지는 튜플 타입(T가 함수가 아닌 경우 never)을 생성한다.
class Person {
constructor(name: string, age: number) {}
}
type PersonConstructorParams = ConstructorParameters<typeof Person>;
const personParams: PersonConstructorParams = ["John", 25];
// personParams는 Person 생성자의 두 매개변수로 이루어진 튜플
ReturnType<T>
함수 T의 반환 타입으로 구성된 타입을 생성한다.
type GreetFunction = () => string;
type GreetFunctionReturnType = ReturnType<GreetFunction>;
const greeting: GreetFunctionReturnType = "Hello, World!";
// greeting은 GreetFunction의 반환 형식인 문자열
Required<T>
T의 모든 프로퍼티가 필수로 설정된 타입을 구성한다.
type PartialPerson = { name?: string; age?: number };
type RequiredPerson = Required<PartialPerson>;
const requiredPerson: RequiredPerson = { name: "John", age: 25 };
// requiredPerson은 모든 속성이 선택되지 않은 형태
https://www.typescriptlang.org/ko/docs/handbook/utility-types.html
Documentation - Utility Types
Types which are globally included in TypeScript
www.typescriptlang.org
TypeScript를 이용해 함수 사용하기
매개변수
function add(x, y) {
return x + y;
}
add(2, 5);
- 매개변수(parameter) : 함수를 정의할 때 사용되는 변수
인자값 = 매개변수 = 파라미터
add(x, y)에서 x, y - 인수(argument) : 함수를 호출할 때 사용되는 값
add(2, 5)에서 2, 5
일급 객체(first-class object)
다른 객체들에 일반적으로 적용 가능한 연산을 모두 지원하는 객체
일급 객체의 조건
- 다른 함수에 매개변수로 제공할 수 있다.
- 함수에서 반환 가능하다.
- 변수에 할당 가능하다.
JavaScript와 TypeScript의 함수는 일급 객체(first-class object)
함수 생성 방식 5가지
: 함수 선언식, 함수 표현식, 화살표 함수 표현식, 단축형 화살표 함수 표현식, 생성자 함수
함수 선언식
function world(name) {
return `hello ${name}`;
}
함수 표현식
let world2 = function (name) {
return `hello ${name}`
}
화살표 함수 표현식
let world3 = (name) => {
return `hello ${name}`;
}
단축형 화살표 함수 표현식
let world4 = (name) => `hello ${name}`;
생성자 함수
되도록 사용하는 것을 권장하지 않음.
let world5 = new Function("name", 'return "hello" + name');
타입스크립트를 이용해서 함수 선언할 때 함수 생성자는 되도록 사용을 권장하지 않는 이유
타입 안전성 부족 :
타입스크립트 컴파일러는 함수 생성자를 통해 생성된 코드의 타입을 미리 검사할 수 없음.
따라서, 런타임 오류가 발생할 가능성이 높아짐.
코드 가독성 저하 :
함수 생성자는 함수의 본문을 문자열 형태로 작성하는데, 일반적인 함수 선언 방식에 비해 가독성이 떨어짐.
코드가 복잡해질수록, 문자열 안에 쓰인 로직을 이해하고 디버깅하는 것이 어려워질 수 있음.
타입스크립트의 주요 목적 중 하나는 코드의 안전성과 오류 최소화를 위해 정적 타입 체킹을 제공하는 것이지만
함수 생성자를 사용할 경우 이러한 장점을 이용하지 못하기 때문에 되도록 사용을 권장하지 않음.
https://ko.javascript.info/constructor-new
new 연산자와 생성자 함수
ko.javascript.info
TypeScript를 이용해 함수 사용하기
· TypeScript 함수 작성시 반환 타입을 추론하도록 하는 것을 권장한다.
· 함수의 매개변수와 인수의 타입이 호환 가능하게 작성한다.
· 인수의 타입을 잘못 전달하면 에러가 발생한다.
함수 선언식 (호이스팅 O)
function world(name: string): string{
return `hello ${name}`;
}
함수 표현식 (호이스팅 X)
let world2 = function(name: string): string {
return `hello ${name}`;
}
화살표 함수 표현식
let world3 = (name: string): string => {
return `hello ${name}`;
}
단축형 화살표 함수 표현식
let world4 = (name: string): string => `
hello ${name}`;
타입추론
· contextual typing : TypeScript 컴파일러는 방정식의 한쪽에만 타입이 있더라도 타입을 추론할 수 있다.
· 이를 통해 프로그램에서 타입을 유지하기 위한 노력을 줄일 수 있다.
일반 함수
let f12 = function(x: number, y: number): number {
return x + y;
}
contextual typing
매개변수 x와 y는 number 타입
let f12: (baseValue: number increment: number) => number = function (x, y) {
return x + y;
}
함수의 매개변수
기본 매개변수
· 함수에 주어진 인자의 수는 함수가 기대하는 매개변수의 수와 일치해야 한다.
function buildName(firstName: string, lastName: string) {
return firstName + "" + lastName;
}
let result1 = buildName("Bob"); // error TS2554: Expected 2 arguments, but got 1.
let result2 = buildName("Bob", "Adams", "Sr."); // error TS2554: Expected 2 arguments, but got 3.
let result3 = buildName("Bob", "Adams");
선택적 매개변수 (Optional Parameter)
· JS에서는 모든 매개변수가 선택적으로, 인수가 없다면 undefined가 된다.
· TS에서도 선택적 매개변수를 사용할 수 있다. (변수명 뒤에 '?')
· 선택적 매개변수는 필수 매개변수의 뒤에 와야 한다.
function buildName(firstName: string, lastName?: string) {
if (lastName) return firstName + "" + lastName;
else return firstName;
}
let result1 = buildName("Bob");
let result2 = buildName("Bob", "Adams");
let result3 = buildName("Bob", "Adams", "Sr."); // error TS2554: Expected 1-2 arguments, but got 3.
기본-초기화 매개변수 (Default Parameter)
· TS에서는 값을 제공하지 않거나, undefined로 했을 때에 매개변수의 값 할당 가능
function buildName(firstName: string, lastName = "Smith") {
return firstName + "" + lastName;
}
let result1 = buildName("Bob"); // "Bob Smith"
let result2 = buildName("Bob", undefined); // "Bob Smith"
let result3 = buildName("Bob", "Adams"); // "Bob Adams"
let result4 = buildName("Bob", "Adams", "Sr."); // error TS2554: Expected 1-2 arguments, but got 3.
나머지 매개변수 (Rest Parameters)
· 컴파일러는 생략 부호(...) 뒤의 인자 배열을 빌드해 함수에서 사용할 수 있다.
· 나머지 매개변수는 매개변수의 수를 무한으로 취급한다.
· 아무것도 넘겨주지 않을 수 있다.
function buildName1 (firstName: string, ...restOfName: string[]) {
// restOfName = [ 'Samuel', 'Lucas', 'MacKinzie' ]
return firstName + " " + restOfName.join(" ");
}
let employeeName = buildName1("Joseph", "Samuel", "Lucas", "MacKinzie");
// Joseph Samuel Lucas MacKinzie
클래스
OOP(Object-Oriented Programming)
· OOP는 컴퓨터 프로그램을 객체(Object)의 모임으로 파악하려는 프로그래밍 패러다임이다.
· 객체(Object)들은 서로 메시지를 주고 받을 수 있으며, 데이터를 처리할 수 있다.
OOP의 장점
· 프로그램을 유연하고 변경을 용이하게 만든다.
· 프로그램의 개발과 보수를 간편하게 만든다.
· 직관적인 코드 분석을 가능하게 한다.
· 객체 지향 프로그래밍의 중요한 특성
· 강한 응집력(Strong Cohension)과 약한 결합력(Weak Coupling)을 지향한다.
- 응집력 : 서로 다른 모듈 간에 상호 의존하는 정도 또는 연관된 관계, 낮아야 좋음.
- 결합력 : 한 모듈 내부의 처리 요소들이 서로 관련되어 있는 정도(독립적 기능 수행), 높아야 좋음.
Class의 요소
멤버(member) | 클래스에 속하는 모든 속성(필드)이나 메서드 |
필드(field) | 클래스의 속성 해당 클래스의 인스턴스와 관련된 일부 특성이나 데이터 |
생성자(constructor) | new 키워드를 사용하여 객체를 생성할 때 호출되는 메서드 |
메소드(method) | 객체가 수행할 수 있는 동작이나 작업 클래스의 인스턴스에서 호출됨. |
· 인스턴스(instance) : new 연산자에 의해서 생성된 객체
자바스크립트트
class Car {
// Field(필드)
brand;
// Constructor(생성자)
constructor(brand) {
this.brand = brand;
}
// Method(메서드)
startEngine() {
console.log(`${this.brand}'s engine started.`);
}
}
// 인스턴스 생성
const myCar = new Car("Toyota");
const anotherCar = new Car("Honda");
// 인스턴스 호출
myCar.startEngine(); // Toyota's engine started.
anotherCar.startEngine(); // Honda's engine started.
타입스크립트
class Person {
name: string;
constructor(name: string) {
this.name = name;
}
say() {
return "Hello, My name is" + this.name;
}
}
let person = new Person("june");
· new를 사용하여 Person 클래스의 인스턴스를 생성한다.
· Person class의 멤버는 name, constructor, say()가 있다.
· 클래스 안에서 "this."를 앞에 붙이면 클래스의 멤버를 의미한다.
접근 제어자 / 상속
접근 제어자
· 속성 또는 메소드로의 접근을 제한하기 위해 사용한다.
· TypeScript에는 3종류의 접근 제어자( public > protected > private )가 존재한다.
· Java와 다르게 package 개념이 없어서 default 접근 제어자는 존재하지 않는다.
접근 제어자(public)
· 프로그램 내에서 선언된 멤버들이 자유롭게 접근할 수 있다.
· TypeScript에서 멤버는 기본적으로 public으로 선언된다.
· 명시적으로 멤버를 public으로 표시할 수도 있다.
class Animal {
public name: string
constructor(theName: string) {
this.name = theName;
}
}
new Animal("Cat").name;
접근 제어자(private)
· 멤버가 포함된 클래스 외부에서의 접근을 막는다.
class Animal {
private name: string
constructor(theName: string) {
this.name = theName;
}
}
new Animal("Cat").name
// error TS2341: Property 'name' is private and only accessible within class 'Animal'.
접근 제어자(protected)
· 멤버가 포함된 클래스와 그 하위 클래스 외부에서의 접근을 막는다.
// 기본 클래스
class Animal {
// protected 필드
protected _name: string;
constructor(name: string) {
this._name = name;
}
// protected 메서드
protected makeSound(): string {
return "일부 일반적인 소리";
}
}
// 파생 클래스 (Animal로부터 상속)
class Dog extends Animal {
private _breed: string;
constructor(name: string, breed: string) {
// 기본 클래스의 생성자 호출
super(name);
this._breed = breed;
}
// 메서드 오버라이딩
makeSound(): string {
return "멍! 멍!";
}
// protected 필드와 메서드 사용하는 추가 메서드
introduce(): string {
return `나는 ${this._name}, ${this._breed} 강아지. ${this.makeSound()}`;
}
}
// Dog 클래스의 인스턴스 생성
const myDog = new Dog("버디", "래브라도");
// 파생 클래스 내에서 protected 멤버에 접근
console.log(myDog.introduce());
// 출력: 나는 Buddy, 래브라도 강아지. 멍! 멍!
console.log(myDog._name);
// 오류: Property '_name' is protected and only accessible within class 'Animal' and its subclasses.
상속
· 상속 : 상위 클래스의 기능을 재사용, 확장하는 문법
· OOP는 상속을 이용하여 존재하는 클래스를 확장해 새로운 클래스를 생성할 수 있다.
· 하위클래스(subclass) : 파생된 클래스
상위클래스(superclass) : 기초 클래스
// 기본 클래스
class Animal {
private _name: string;
constructor(name: string) {
this._name = name;
}
// 이름을 반환하는 게터
get name(): string {
return this._name;
}
// 메서드
makeSound(): string {
return "일부 일반적인 소리";
}
}
// 파생 클래스 (Animal로부터 상속)
class Dog extends Animal {
private _breed: string;
constructor(name: string, breed: string) {
// 기본 클래스의 생성자 호출
super(name);
this._breed = breed;
}
// 메서드 오버라이딩
makeSound(): string {
return "멍! 멍!";
}
// 파생 클래스의 추가 메서드
getBreed(): string {
return this._breed;
}
}
// 인스턴스 생성
const genericAnimal = new Animal("일반 동물");
const myDog = new Dog("버디", "래브라도");
// 기본 클래스의 메서드 사용
console.log(genericAnimal.name); // 출력: 일반 동물
console.log(genericAnimal.makeSound()); // 출력: 일부 일반적인 소리
// 파생 클래스의 메서드 사용
console.log(myDog.name); // 출력: 버디
console.log(myDog.makeSound()); // 출력: 멍! 멍!
console.log(myDog.getBreed()); // 출력: 래브라도
Getters & Setters / readonly / static
Getters & Setters
· class의 속성에 직접 접근하는 것을 막고, getter, setter 함수를 사용해 값을 받아오거나 수정한다.
· 속성에 직접 접근해 수정하면 데이터 무결성이 깨질 수 있다. (캡슐화 권장)
· 비공개로 설정한 속성은 private로 설정하고, 속성값을 읽고 수정하는 getter/setter 함수를 사용한다
class Person {
private _name: string
get name() {
return this._name;
}
set name(name: string) {
if (name.length > 10) {
throw new Error("name too long")
}
this._name = name;
}
}
let person = new Person();
console.log(person.name);
person.name = "june";
console.log(person.name);
person.name = "junejunejunejune";
readonly
· 속성을 읽기 전용으로 설정해 변경할 수 없게 만든다.
· 선언될 때나 생성자에서 값을 설정하면 이후 수정할 수 없다.
class Person {
readonly age: number = 20 // 선언 초기화
constructor(age: number) {
this.age = age
}
}
let person = new Person(10); // 생성자 초기화
person.age = 30;
static
· 전역 멤버 : 객체마다 할당되지 않고 클래스의 모든 객체가 공유하는 멤버로, 범용적으로 사용되는 값에 설정한다.
· "클래스명."을 앞에 붙여 static 멤버에 접근할 수 있다
· ES6에서는 메소드 전용 속성에는 선언이 안 되었으나, TypeScript에서는 사용할 수 있다.
class MathUtility {
static PI: number = 3.14159;
static multiply(x: number, y: number): number {
return x * y;
}
}
// static 프로퍼티에 접근
console.log("PI:", MathUtility.PI);
// static 메소드를 호출
const result = MathUtility.multiply(5, 3);
console.log("Multiplication result:", result);
추상 클래스
· 추상 클래스 : abstract로 정의하며, 다른 클래스들이 파생될 수 있는 기초 클래스
· 추상 클래스는 직접 인스턴스를 생성할 수 없다.
· 추상 메소드는 클래스에는 구현되어 있지 않고, 파생된 클래스에서 구현해야 한다.
abstract class Shape {
protected color: string;
constructor(color: string) {
this.color = color;
}
abstract calculateArea(): number;
displayArea(): void {
const area = this.calculateArea();
console.log(`Color: ${this.color}, Area: ${area}`);
}
}
class Circle extends Shape {
radius: number;
constructor(radius: number, color: string) {
super(color); // 상위 클래스(Shape 클래스)의 생성자 호출
this.radius = radius;
}
calculateArea(): number {
return Math.PI * this.radius * this.radius;
}
}
const shape = new Shape(8, "blue"); // 에러 : 추상클래스의 인스턴스는 생성 불가능
const circle = new Circle(5, "red");
circle.displayArea();
추상 클래스를 활용한 디자인 패턴(Template Method Pattern)
· 디자인 패턴 : 프로그램의 일부분을 서브 클래스로 캡슐화해 전체 구조를 바꾸지 않고, 특정 단계의 기능을 바꾸는 것
· 전체적인 알고리즘은 상위 클래스에서 구현, 다른 부분은 하위 클래스에서 구현한다.
· 전체 구조는 유사하지만 부분적으로 다른 구문으로 구성된 메소드의 코드 중복을 최소화할 수 있다.
'교육 > 엘리스 SW 트랙' 카테고리의 다른 글
[엘리스sw] 6주차 1일 - npm과 모듈, Express (0) | 2024.01.28 |
---|---|
[엘리스sw] 5주차 5일 - 인터페이스, 제네릭 (0) | 2024.01.25 |
[엘리스sw] 5주차 1일 - Node.js와 MongoDB I (0) | 2024.01.20 |
[엘리스sw] 4주차 3일 - async/await, API (0) | 2024.01.15 |
[엘리스sw] 4주차 1일 - 비동기통신 Promise (0) | 2024.01.14 |