이 블로그는 광고 클릭 수익으로 운영됩니다!
괜찮으시다면 광고 차단을 풀어주세요 ㅠㅠ

게시글

강좌53 - JavaScript - 일 년 전 등록 / 9달 전 수정

오버라이딩과 오버로딩

조회수:
0
이 블로그는 광고 클릭 수익으로 운영됩니다!
괜찮으시다면 광고 차단을 풀어주세요 ㅠㅠ
이 블로그는 광고 클릭 수익으로 운영됩니다!
괜찮으시다면 광고 차단을 풀어주세요 ㅠㅠ

안녕하세요. 이번 시간에는 자바스크립트에서 오버라이딩(overriding)오버로딩(overloading)의 차이에 대해 알아보겠습니다! 자바스크립트 강좌를 안 쓰려고 했는데 자꾸 쓰게 되네요. 자바스크립트의 마력이랄까요. ㅎㅎ

자바를 배우신 분들은 오버라이딩과 오버로딩에 대해 잘 아실테지만 자바스크립트로 프로그래밍을 시작하신 분들은 용어가 다소 생소할 수 있겠네요. 심지어 용어가 비슷하기도 해서 헷갈리기도 합니다.

오버로딩

스타크래프트의 오버로드와는 아무 상관도 없습니다. (철자가 다릅니다 ㅎㅎ) 자바스크립트에는 사실 없는 개념입니다. 자바스크립트는 함수의 매개변수가 자유롭기 때문입니다. 하지만 다른 언어에서는 매개변수의 개수 또는 자료형에 따라서 함수를 다르게 선언하는 경우가 있습니다. 아래는 자바의 경우입니다.

void overload(){
  System.out.println("매개변수 0개");
}

void overload(int i, int j){
  System.out.println("매개변수 "+ i + " 그리고 " + j);
}

void overload(double d){
  System.out.println("매개변수 " + d);
}

자바스크립트에서는 위와 같이 하면 제일 아래에 선언한 함수가 같은 이름의 함수를 덮어씌워버립니다. 따라서 자바스크립트는 하나의 함수로 여러 개의 매개변수 또는 다양한 자료형의 매개변수를 처리하는 기법이 필요합니다.

여러 라이브러리들이 이렇게 가변적인 매개변수를 받습니다. 제이쿼리의 경우 $ 함수는 다재다능합니다. $(function() {})처럼 함수를 받으면 이벤트 리스너를, $(document)를 하면 DOM을, $('#zero')를 하면 선택자를 처리합니다. 제이쿼리의 on함수도 on('click', function() {})이면 이벤트 리스너를, on('click', '#zero', function() {})이면 이벤트 델리게이션을 처리합니다. 자료형이 다를 때도 있고, 매개변수 개수가 다를 때도 있습니다.

예를 들어 매개변수로 문자열 두 개와 콜백, 또는 옵션 객체 하나와 콜백, 또는 그냥 콜백 한 개만 가지는 함수를 생각해봅시다. 콜백은 문자열이나 옵션이 뭔지 console.log를 찍어주는 함수라고 칩시다. 이처럼 하나의 함수가 세 가지 경우를 모두 처리해야 합니다. 한 번에 만들기 어렵다면 나눠서 생각하면 됩니다.

function overload(a, b, c) {}

위와 같은 함수를 먼저 만들고, 각각의 경우를 생각해봅시다. 문자열 두 개와 콜백을 가지는 경우는 a,b가 문자열, c가 콜백일 것입니다. 옵션 객체와 콜백을 가지는 경우는 a가 옵션 객체, b가 콜백일 것이고요. 그냥 콜백만 가지면 a가 콜백일 것입니다. 이것을 분기 처리하면 됩니다.

function overload(a, b, c) {
  if (typeof c === 'function') { // 문자열 두 개와 콜백
    c(a, b);
  } else if (typeof b === 'function') { // 옵션 객체와 콜백
    b(a);
  } else { // 콜백 하나
    a();
  }
}

위와 같이 하면 됩니다. 각각의 경우를 모두 대응하고 있습니다. 자바가 더 보기 좋을 수도 있습니다. 하지만 우리는 자바가 아닌 자바스크립트를 하고 있기 때문에 어쩔 수 없습니다.

function callback(a, b) {
  if (b) {
    console.log('문자열', a, b);
  } else if (a) {
    console.log('옵션 객체', a);
  }  else {
    console.log('매개변수 없음');
  }
}
overload('zero', 'babo', callback); // 문자열 zero babo
overload({ name: 'zero', value: 'babo' }, callback); // 옵션 객체 { name: 'zero', value: 'babo' }
overload(callback); // 매개변수 없음

정상적으로 실행됩니다. 재밌는 점은 callback도 오버로딩과 비슷한 동작을 하고 있다는 것입니다. 저는 자바스크립트의 자유도가 참 좋습니다.

오버라이딩

자바스크립트 객체의 상속받은 부모의 메소드를 재정의하는 것을 의미합니다. 오버라이딩이라는 개념은 존재하지만 자바같은 언어와는 또 다릅니다. 매개변수가 자유롭고, 리턴값의 자료형도 자유롭습니다. ES5 코드로 설명하겠습니다.

var Animal = function() {
};
Animal.prototype.move = function() {
  console.log('동물이 움직여요');
};

var Cat = function() {
  Animal.apply(this, arguments); // 속성 상속받는 방법
}
Cat.prototype = Object.create(Animal.prototype); // 프로토타입 상속 방법
Cat.prototype.constructor = Cat; // 버그 패치

console.log(new Animal().move()); // 동물이 움직여요
console.log(new Cat().move()); // 동물이 움직여요

Cat.prototype.move = function(sound) { // 오버라이딩
  console.log(sound + ' 움직여요');
  return '야옹';
};

console.log(new Cat().move('살금살금')); // 살금살금 움직여요

위의 코드는 자바스크립트에서 객체를 상속하는 코드입니다. 고양이가 동물을 상속하고 있습니다. 상속 방법은 알아두시면 좋습니다. 관련 강좌 는 여기에 있습니다. 

Animal과 Cat 모두 move라는 메소드를 가지고 있습니다. Cat에 move를 추가하기 전에는 Cat은 Animal의 move를 상속받아 사용했습니다. 그런데 Cat이 다시 move를 재정의하니까 Animal의 move 대신 Cat의 move가 호출됩니다. 즉 부모 객체의 메소드를 덮어씌운 것입니다. 게다가 매개변수도 하나 받고 리턴 값도 생겼습니다.

자바와는 달리 부모 메소드를 오버라이딩할 때 매개변수와 리턴 자료형이 달라도 됩니다. 이는 잘 생각해보면 당연합니다. 자바스크립트에 오버로딩이란 개념이 없기 때문입니다.

undefined

다른 언어에서는 위와 같이 비유하기도 합니다. 하지만 자바스크립트에서는 위 그림이 적용되지 않는다는 것 알아두시면 되겠습니다.

오늘도 간단하게 오버로딩과 오버라이딩의 개념을 알아보았습니다. 물론 배우고 나서도 계속 이름은 헷갈리지만, 이런 두 개가 있다는 것을 알고 계시면 좋겠습니다!

목록
투표로 게시글에 관해 피드백을 해주시면 많은 도움이 됩니다. 오류가 있다면 어떤 부분에 오류가 있는지도 알려주세요! 잘못된 정보가 퍼져나가지 않도록 도와주세요.
Copyright © 2016- 무단 전재 및 재배포 금지

댓글

4개의 댓글이 있습니다.
9달 전
안녕하세요?

Cat.prototype.constructor = Cat; // 버그 패치

버그 패치란게?? 무슨 버그가 있는건가요??

Cat.prototype 이 Animal.prototype 로 바껴서..
prototype 의 생성자 부분만 Cat으로 변경하는 건가요??
9달 전
객체 상속 강좌에 나와있는데 prototype과 constructor는 부모 자식 관계라서 prototype.constructor를 하면 자기자신이 나와야합니다. 하지만 js에서 그렇지 않은 버그가 있어 수정하는 것입니다.
일 년 전
오버로딩에서
overload({ name: 'zero', value: 'babo' }, callback); // 옵션 객체 {}
부분이 옵션객체가 비어있는데 옵션객체 { name: 'zero', value: 'babo' }
라고 출력되야하지 않나요?? 직접 코드를 실행했을때는 나오던뎅...ㅎㅎ
일 년 전
감사합니다~
일 년 전
https://www.reddit.com/r/ProgrammerHumor/comments/3rmikr/free_drink_anyone/ 안녕하세요 어떻해 쪽지 드리는지 몰라서 여기에 물어봐도 되나요??
var you_drink;
var reverse = function(s){return s.split("").reverse().join("")}
var bartender = {str1:'ers', str2:reverse('rap'), str3:'amet', request:function(preference){return preference + "secret word:" + this.str2 + this.str3 + this.str1}} bartender.request(your_drink)
console창 결과 - undefined.secretword.parameters 즉, 원하는 음료, 재료 말해주면 맛잇게 만들어주겟다는거죠??
일 년 전
undefined 부분에 원하시는 음료를 넣어서 말씀하시면 될 것 같네요 ㅎㅎ
일 년 전
자바에서는 타입이 정확하게 지정되어야 하기 때문에 오버로딩이 필수인가봐요. 자바스크립트에서 오버로딩/오버라이딩은 주로 어느 상황에 사용하는지요?
일 년 전
오버로딩은 하나의 함수를 유연하게 활용하고 싶을 때 사용하고(보통 라이브러리 제작 같이), 오버라이딩은 부모 객체의 메소드를 덮어씌울 때 사용합니다(부모 객체 메소드 구체화).
일 년 전
답변 감사합니다. 오버라이딩을 할 때 자바랑 자바스크립트 모두 부모의 메소드를 변경하면 원래 메소드는 사용못하는거죠?
일 년 전
자바는 모르겠는데 자바스크립트는 할 수는 있습니다. Animal.prototype.move.bind(this)() 이런 식으로요