[JavaScript] 오버라이딩, 오버로딩

Sieun Dorothy Lee·2023년 12월 6일
0

오버라이딩 & 오버로딩 개념

  • 오버라이딩 (overriding) : 자식 클래스에서 부모 클래스의 기능을 재정의하는 방법
  • 오버로딩 (overloading) : 같은 이름을 가진 함수를 매개변수의 타입과 개수를 다르게 작성하는 방법

여기서 의문.
자바스크립트는 '함수를 작성할 때 정의한 매개변수'와 '사용할 때 작성한 매개변수'의 타입과 개수가 달라도 알아서 다음과 같이 처리한다.

function test(a, b, c) {
	console.log(a, b, c)
}

test(1, 2, 3) // 1 2 3
test(1, 2) // 1 2 undefined
test(1, 2, 3, 4) // 1 2 3
test('a', 'b', 1) // a b 1

따라서, 자바스크립트는 문법적으로 오버로딩을 제공하지 않는다.
대신 생성자 함수를 이용해 일반 객체지향 언어의 클래스를 흉내 내듯이 오버로딩 또한 흉내낼 수 있다 (아래에 작성)

오버라이딩

오버라이딩에 대해 좀 더 알아보자.
자바스크립트의 오버라이딩의 종류로는 생성자 오버라이딩, 메서드 오버라이딩이 있다.
오버라이딩은 부모 클래스, 자식 클래스의 개념이 나오므로, 먼저 클래스 상속 개념에 대한 선행 지식이 요구된다.

extends를 사용하여 부모 클래스를 상속받게 되면, 자식 클래스는 부모 클래스의 메서드, 속성을 '그대로' 사용할 수 있다.
그런데, '그대로' 사용하기 싫다면?
-> 오버라이딩을 해보자.

메서드 오버라이딩

개발을 하다 보면 부모 메서드 전체를 교체하지 않고, 부모 메서드를 토대로 일부 기능만 변경하고 싶을 때가 생긴다. 이럴 때는 커스텀 메서드를 만들어 작업하게 되는데, 이미 커스텀 메서드를 만들었더라도 이 과정 전후에 부모 메서드를 호출하고 싶을 때가 있다.

  • 부모 클래서의 기능을 사용하지 않고 자식 클래스에서 구현한 기능을 사용하고 싶은 경우
  • 부모 클래스의 기능을 자식 클래스에서 확장하고 싶은 경우

이럴 때는 super 키워드를 사용한다.

class Animal {

  constructor(name) {
    this.speed = 0;
    this.name = name;
  }

  run(speed) {
    this.speed = speed;
    alert(`${this.name}가 속도 ${this.speed}로 달립니다.`);
  }

  stop() {
    this.speed = 0;
    alert(`${this.name}가 멈췄습니다.`);
  }

}

class Rabbit extends Animal {
  hide() {
    alert(`${this.name}가 숨었습니다!`);
  }

  stop() {
    super.stop(); // 부모 클래스의 stop을 호출해 멈추고,
    this.hide(); // 숨습니다.
  }
}

let rabbit = new Rabbit("흰 토끼");

rabbit.run(5); // 흰 토끼가 속도 5로 달립니다.
rabbit.stop(); // 흰 토끼가 멈췄습니다. 흰 토끼가 숨었습니다!

부모 클래스인 Animal을 상속받은 자식 클래스 Rabbit은 커스텀 메서드인 stop을 작성하여, 해당 메서드에서는 부모 클래스의 stop 메서드와 다른 행동을 추가적으로 하도록 함

생성자 오버라이딩

위의 예시 코드에서 Rabbit 클래스는 별도의 생성자(consturctor)가 없다. 이러한 경우에는 아래와 같은 코드가 생략되었다고 생각할 수 있다.

class Rabbit extends Animal {
  // 자체 생성자가 없는 클래스를 상속받으면 자동으로 만들어짐
  constructor(...args) {
    super(...args);
  }
}

따라서 Rabbit 클래스의 객체인 rabbit은 rabbit.speed가 0이고 rabbit.name = "흰 토끼"이다.
이때, Rabbit 클래스의 객체에는 추가적인 속성이 있으면 좋겠다 생각이 든다면,
커스텀 생성자를 추가하여 생성자 오버라이딩을 사용해보자.

class Animal {
  constructor(name) {
    this.speed = 0;
    this.name = name;
  }
  // ...
}

class Rabbit extends Animal {

  constructor(name, earLength) {
  	super(name);
    this.earLength = earLength;
  }

  // ...
}


let rabbit = new Rabbit("흰 토끼", 10); 
console.log(rabbit.name); // 흰 토끼
console.log(rabbit.earLength); // 10
  • super()는 부모 클래스의 생성자를 호출하는 행위이고, 이는 반드시 this를 사용하기 전에 작성되어야 함
    -> super()가 작성되지 않으면 발생하는 에러 : ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor

오버로딩

분기처리 방식을 이용하여, 오버로딩을 흉내낼 수 있다.
(매개변수의 타입으로 분기처리를 하려면 typeof를 사용)

function overload(a,b) {
  if(b)	console.log(a,b)
  else {
    console.log(a)
  }
}
overload(1) // 1
overload(1,2) // 1 2

참고

https://ko.javascript.info/class-inheritance#ref-403

profile
성장하는 중!

0개의 댓글