[JavaScript] Class의 Method Overriding

Joowon Jang·2025년 1월 7일

JavaScript

목록 보기
13/17

Class와 Prototype - 참고
https://velog.io/@juwon98/JavaScript-Class-Prototype

Overloading과 Overriding의 차이

Overloading과 Overriding은 단어도 비슷하고, 둘을 혼동하는 경우가 많지만 엄연히 다른 개념이다.
우선, JavaScript에는 함수(method)의 Overloading이 존재하지 않는다.

객체 지향 언어인 Java에서 정의하는 Overloading은 다음와 같다.
-> Overloading이란, 한 클래스 내에 이미 사용하려는 이름과 같은 이름의 메소드가 있더라도 매개변수의 개수 또는 타입이 다르면, 같은 이름을 사용해서 메소드를 정의할 수 있다.
JavaScript는 타입이 없는 동적 언어 타입이 없는 동적타입 언어이기도 하고, Overloading을 지원하지 않는다.

반면에, JavaScript의 class에서도 Overriding은 지원한다.
-> Overriding이란, 부모 클래스로부터 상속받은 메소드를 자식 클래스에서 재정의하는 것을 말한다.


JavaScript의 Overriding

아래 예시를 통해 알아보자.

// 부모 class
class Exam {
  #kor = 0;
  #math = 0;

  constructor(kor = 0, math = 0) {
    this.#kor = kor;
    this.#math = math;
  }

  total() {
    return this.#kor + this.#math;
  }
  avg() {
    return this.total() / 2;
  }
}

// Exam을 상속받은 NewExam class
class NewExam extends Exam {
  #eng = 0;
  
  constructor(kor = 0, math = 0, eng = 0) {
    super(kor, math);
    this.#eng = eng;
  }

  total() {
    return super.total() + this.#eng;
  }
}

let ex = new Exam(10, 20);
let nex = new NewExam(10, 20, 30);

console.log(ex.total()); // 30
console.log(nex.total()); // 60

console.log(ex.avg()); // 15
console.log(ex.avg()); // 30

Exam과 Exam을 상속받은 NewExam class가 있고,
두 class는 total이라는 같은 이름의 인스턴스 메서드를 가지고 있지만, avg 메서드는 Exam만 가지고 있다.

여기서, Exam의 인스턴스인 ex에서 ex.total()을 호출했을 때는 Exam class에 존재하는 total 메서드를 실행해서 10 + 20 -> 30이 출력된다.
NewExam의 인스턴스인 nex에서 nex.total()을 호출하면, Overriding하여 새롭게 선언한 NewExam의 total 메서드를 실행해서 Exam의 total() 결과(30) + 30 -> 60이 출력된다.

하지만, avg 메서드의 경우는 조금 특이하다.
ex.avg()를 호출하면 Exam의 total()의 결과(30) / 2 -> 15가 출력된다.
nex.avg()를 호출하면 NewExam class에는 avg 메서드가 존재하지 않기 때문에, 상속받은 Exam의 avg 메서드를 실행한다.
그런데, avg 메서드에 있는 this.total()은 Exam이 아닌 NewExam의 total 메서드를 실행하게 된다.

이렇게 동작하는 이유(과정)은 아래에서 알아보자.

동적 디스패치(Dynamic Dispatch)와 this

동적 디스패치: 런타임(프로그램 실행 중)에 객체의 타입에 따라 호출할 메서드를 결정하는 것
정적 디스패치(Static Dispatch): 호출할 메서드를 컴파일타임(프로그램 실행 전)에 결정하는 것

JavaScript는 객체지향 언어로, 메서드를 호출할 때 메서드의 소유 클래스뿐만 아니라 실제 객체의 타입에 따라 어떤 메서드를 실행할지 결정한다. (동적 디스패치)
여기서, avg 메서드를 호출한 객체가 어떤 class의 인스턴스인지(this.total()의 this가 무엇을 가리키는지)가 중요하다.

ex.avg() 호출 시: this는 ex를 참조 (Exam의 인스턴스)
nex.avg() 호출 시: this는 nex를 참조 (NewExam의 인스턴스)

this.total()을 호출할 때, nex는 NewExam 클래스의 인스턴스이기 때문에, nex의 가장 가까운 메서드 선언(Overriding된 메서드)인 NewExam의 total 메서드를 실행한다.

This - 참고
https://velog.io/@juwon98/JavaScript-this

profile
깊이 공부하는 웹개발자

0개의 댓글