본문 바로가기
Programming/Typescript

[Typescript] Typescript와 OOP 언어의 Function Overloading 비교

by SpiralMoon 2024. 3. 7.
반응형

Typescript와 OOP 언어의 Function Overloading 비교

타입스크립트와 객체지향 언어의 함수 오버로드의 차이점에 대해 알아보자

사전 지식

 

함수 오버로드 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 함수 오버로드(영어: Function overloading)는 다양한 에이다(Ada), C#, C++, 자바(Java) 등의 다양한 프로그래밍 언어에서 사용되는 함수의 특징으로, 같은 함수 이름을 가

ko.wikipedia.org


Typescript와 OOP 언어의 함수 오버로드 정의 방법과 차이점

스타크래프트 오버로드

프로그래밍 언어들은 다형성을 만족시키기 위해 함수 오버로드를 지원한다. 그러나 타입스크립트에서는 일반적인 객체지향 언어에서의 함수 오버로드와 다른 형태로 지원한다.

 

우선 Java, C#, C++ 등 일반적인 객체지향 언어에서는 함수 오버로드를 다음과 같이 정의한다.

 

public class Calculator {

    public int add(int x, int y) {
        return x + y;
    }
    
    public String add(String x, String y) {
        return x.concat(y);
    }
}

...

// 사용 예시
public static void main(String[] args) {
    Calculator calc = new Calculator();
    
    System.out.println(calc.add(5, 3)); // 출력: 8
    System.out.println(calc.add("Hello", " World")); // 출력: Hello World
}

 

  1. 오버로드 할 함수(메소드)의 이름을 동일하게 짓는다.
  2. 각 함수별로 매개변수의 타입과 수를 다르게 정의한다.
  3. 각 함수별로 함수의 내용을 정의한다.

그러나 타입스크립트에서는 함수 오버로드를 다음과 같이 정의한다.

 

// Class method overload

class Calculator {

    add(x: number, y: number): number;
    add(x: string, y: string): string;
    
    add(x: any, y: any): any {
        if (typeof x === 'number' && typeof y === 'number') {
            return x + y;
        } else if (typeof x === 'string' && typeof y === 'string') {
            return x.concat(y);
        }
    }
}

...

// 사용 예시
const calc = new Calculator();

console.log(calc.add(5, 3)); // 출력: 8
console.log(calc.add('Hello', ' World')); // 출력: Hello World

// ------------------------------------------------------------------

// Function overload

function add(x: number, y: number): number;
function add(x: string, y: string): string;

function add(x: any, y: any): any {
    if (typeof x === 'number' && typeof y === 'number') {
        return x + y;
    } else if (typeof x === 'string' && typeof y === 'string') {
        return x.concat(y);
    }
}

...

// 사용 예시
console.log(add(5, 3)); // 출력: 8
console.log(add('Hello', ' World')); // 출력: Hello World

 

 

  1. 오버로드 할 함수(메소드)의 이름을 동일하게 짓는다.
  2. 각 함수 시그니처별로 매개변수의 타입과 수를 다르게 정의한다.
  3. 각 함수 시그니처의 모든 타입 범위를 포함시키는 함수의 내용을 정의한다.

 

객체지향 언어에서는 함수 오버로드를 구성할 때 내용이 각자 다른 여러개의 함수를 정의할 수 있지만, 타입스크립트에서는 내용을 가진 단 하나의 함수여러개의 함수 시그니처를 같이 정의해야한다.

 

즉, 타입스크립트에서는 여러 함수 시그니처에 대한 내용을 하나의 함수에서 작성해야한다.

 

function add(x: number, y: number): number; // 함수 시그니처 A
function add(x: string, y: string): string; // 함수 시그니처 B

function add(x: any, y: any): any { // 실제로 호출되는 함수
    if (typeof x === 'number' && typeof y === 'number') { // 시그니처 A를 판단하는 조건
        return x + y; // 시그니처 A의 로직
    } else if (typeof x === 'string' && typeof y === 'string') { // 시그니처 B를 판단하는 조건
        return x.concat(y); // 시그니처 B의 로직
    }
}

 

함수 시그니처는 타입 추론을 위해서만 존재하는 타입 정보이므로 자바스크립트로의 컴파일 이후에는 사라진다. 컴파일 결과물로 남는 것은 내용이 작성된 하나의 함수 뿐이다.

 

이러한 특징은 하나의 함수에서 시그니처를 구분하고 그에 대응하는 내용 코드를 모두 작성해야하는 것을 의미하며 다음과 같은 특징을 가진다.

  1. 함수 시그니처가 추가되면 기존 함수를 수정해야한다.
  2. 함수 시그니처의 수가 많아지면 기존 함수의 내용이 길어진다.
  3. 함수 시그니처의 파라미터가 복잡하면 시그니처를 구분하는 조건문도 어려워질 수 있다.
  4. 하나의 함수에는 모든 함수 시그니처를 구분하는 조건문이 작성되어야 한다.

즉, 수정 단계에서 휴먼 에러의 발생 가능성이 높다.


차이점이 발생하는 이유

타입스크립트 코드는 자바스크립트 런타임으로 실행되기 때문에 자바스크립트 특징에 영향을 받는다.

 

우선 자바스크립트에서는 아래와 같은 언어적 특성으로 인해 함수 오버로드가 존재하지 않는다.

  1. 유연한 매개변수 : 함수 호출 시 파라미터의 타입이나 수에 대한 엄격한 규칙이 없다.
  2. 동적 함수 재정의 : 런타임중에 함수를 얼마든지 재정의 할 수 있다.
  3. 함수는 일급객체 : 함수는 변수로 취급되므로 동일한 이름으로 여러개를 정의할 수 없다.

따라서 타입스크립트에서는 자바스크립트의 한계를 해결하기 위해 함수 시그니처를 사용하는 방법으로 오버로드를 모방하고 있다. 객체지향 언어와 동일한 방식으로 함수 오버로드가 작동될 수 없다.

반응형

댓글