4줄 요약)
1. 다형성은 "객체지향"의 특성 중 하나로, 한 가지 형태로 여러 가지 기능을 수행하는 특성을 뜻한다.
2. 호출 시그니쳐는 함수가 받아들이는 인자의 타입 및 형태이다.
3. 함수 오버로딩은 한개의 함수가 여러 개의 호출 시그니쳐 및 그에 대응되는 실행기능을 갖는 것을 말한다.
4. 하나의 이름을 갖는 함수가 여러 호출시그니처를 가짐으로써 "다형성" 특성이 구현된다.
위의 포스팅의 말미에서 객체지향의 특성에 대해 간단하게 설명했었다.
이 게시글에선 polymorphism(다형성)에 대해 좀더 알아보고
call signature(호출 시그니쳐)와 function overloading(함수 오버로딩)을 통해 어떤 식으로 다형성이 구현되는 모습을 살펴보겠다.
polymorphism(다형성)?
폴리모피즘이라는 단어가 생소할 수 있으니, 사전적 정의를 살펴보자.
- polymorphism 의 사전적 의미
poly: 여러가지의, 여러 개의
폴리는 여러개를 뜻하는 접두어이다.
화학, 생물학을 통해 우리는 이미 폴리~~ 단어를 많이 들어봤다.
polypeptide(폴리펩타이드): 단백질: 펩타이드결합이 여러 개 있다는 뜻이다.
polyester(폴리에스테르): 석유로 만드는 옷감 에스테르결합이 여러 개 있다는 뜻이다.
morphism: 형태, 상태변화
morph(모프): 변화하다.
metamorphosis(변신): 프란츠 카프카의 소설 "변신"의 영어제목.
워크래프트 3 악마사냥꾼의 궁극기 "탈태" 또는 "메타몽"의 원래 이름
이처럼 polymorphism은 다소 생소 할 수 있지만
사실 poly와 morph는 이미 여러번 접해서 친숙한 영단어들이다.
소싯적에 판타지 소설좀 읽은 분은 폴리모피즘 자체가 이미 익숙할 것이다.
"폴리모프"가 드래곤따위의 대단한 존재가 사용하는 변신스킬 이름으로 종종 등장하기 때문이다.
- 프로그래밍에서의 polymorphism:
polymorphism(다형성):
같은 이름을 사용하는 객체가 다른 특성이나 행동을 보유할 수 있는 특성.
ex)
"hi"+ "hi" === "hihi"
두 문자열을 이은 하나의 문자열을 만들어주는 연산
6 + 7 === 13
두 숫자를 더해주는 연산
위의 예시에서 "+" 연산자는 피연산자의 타입에 따라 전혀 다른 기능을 수행하고 있다.
이렇게 같은 이름으로 여러가지 다른 기능을 갖고 있는 것을 다형성이라 한다.
Call signature(호출 시그니쳐)
함수를 호출할 때, 대입되어야하는 인자들의 타입 및 형태.
일반적으로 타입스크립트에선 함수코드에 마우스커서를 올리면 호출 시그니쳐를 살펴볼 수 있다.
호출시그니쳐 분리및 함수 오버로딩:
타입스크립트에서는 함수를 선언할 때, 매개변수의 타입을 꼭 지정해주어야 한다.
하지만 "interface"나 "type" 선언을 통해 호출시그니쳐를 함수 선언에서 분리해 줄 수 있다.
"type"을 이용해 호출시그니처를 먼저 정의하기.
// 화살표 함수의 타입을 지정했다.
type ArrowCS = (a: number, b: number) => number;
//변수에 함수를 저장했다. a와 b에는 타입을 써주지 않아도 된다.
const ArrowAdd: ArrowCS = (a, b) => a + b
// 타입지정은 화살표함수로 했지만, 일반 함수도 type ArrowCS를 사용할 수 있다.
const NormalAdd: ArrowCS = function (a,b) {
return a+b
};
"interface"를 이용해 호출시그니처를 먼저 정의하기.
interface NormalCS {
(arg1: string, arg2: number): number;
}
//일반 함수
const InterfaceFunction: NormalCS = function (arg1, arg2) {return arg2;};
//화살표 함수
const InterfaceArrow: NormalCS = (arg1, arg2) => arg2;
위의 두 코드처럼 호출시그니처를 분리하는 함수는
"function"키워드로 선언을 시작하지 않고, const나 let을 통해 선언한 변수에 함수를 저장하는
"익명함수"로만 구현할 수 있다.
호출 시그니처를 이용한 함수 오버로딩 구현
1. 인자의 개수가 여러 개인 경우
type ForOverloading = {
(a: number, b: number): number,
(a: number, b: number, c:number): number
}
//인자의 개수가 세개인경우 세개를 모두 더한다.
const newAdd: ForOverloading = (a, b, c?:number) => {
if (c) return a + b + c
return a + b;
}
//인자의 개수와 상관없이 받는 함수
type ForOverloading = {
(a: number, b: number): number,
(a: number, b: number, ...args: number[]): number
}
const newAdd: ForOverloading = (a, b, ...args: number[]) => {
let sum = a + b;
args.forEach(arg => sum += arg);
return sum;
};
예시 2: 인자의 타입이 여러 개인 경우
type SpecialAdd = (a: number | string, b: number | string) => number | string;
//SpecialAdd 함수는 number 두개를 입력 받을때와
// string두개를 입력받을때 서로다르게 동작한다.
const specialAdd: SpecialAdd = (a, b) => {
if (typeof a === "number" && typeof b === "number") {
return a + b;
}
else if(typeof a ==="string" && typeof b ==="string") {
return a + b;
}
else {
throw TypeError;
}
}
+@
제네릭을 이용하면 더 쉽게 구현할 수 있다.
type SuperPrint = {
<T>(arr: T[]):void
}
const superPrint: SuperPrint = (arr) => {
arr.forEach(i => console.log(i))
}
superPrint([1,2,3]) // number[]
superPrint(["a", "b", "c"]) // string[]
superPrint([1,2, "a", true]) // 이것도전부 타입을 잡아준다.
//사진참고
읽어주셔서 감사합니다.
오탈자 및 오류를 발견할시 댓글로 지적해주세요.
내용참고: https://www.youtube.com/watch?v=FotK-GR0kLI&embeds_euri=https%3A%2F%2Fnomadcoders.co%2F&embeds_origin=https%3A%2F%2Fnomadcoders.co&source_ve_path=MjM4NTE&feature=emb_title
썸네일 출처
'it공부 (개념) > javascript' 카테고리의 다른 글
Access Modifier(접근제어자)란? +@ 게터 와 세터, 타입스크립트 예제. (public, private, protected) (0) | 2023.02.08 |
---|---|
Typescript "Type" 키워드 사용하기 (0) | 2023.02.07 |
자바스크립트 ES6 arrow function(화살표 함수) 개념 및 타입스크립트 예제 +@ python lambda (0) | 2023.02.01 |
Decorator(데코레이터) 와 Meta-programming(메타프로그래밍): Typescript(타입스크립트) 예제 (0) | 2023.01.31 |
prototype(프로토타입)과 객체지향 프로그래밍: Typescript Decorator를 위한 Javascript(자바스크립트) 사전지식 (0) | 2023.01.29 |