[JavaScript] - 다중상속

Lee Jeong Min·2021년 9월 22일
3
post-thumbnail

책 모던 JavaScript를 읽으면서 프로토타입, 클래스를 배운 후 JavaScript에서는 다른 언어에서 사용할 수 있는 다중 상속을 사용할 수 있는 지 직접 정리해본 글입니다.

다중 상속이란?

다중상속(Multiple inheritance)이란 객체 지향 프로그래밍의 특징 중 하나이며, 어떤 클래스가 하나 이상의 상위 클래스로부터 여러 가지 행동이나 특징을 상속받을 수 있는 것을 말한다.

출처: 위키백과 - 다중 상속

위 정의와 같이 다중 상속은 클래스가 여러개의 부모로 부터 상속을 받을 수 있는 지와 관련한 것입니다. 이번에 자바스크립트에 대해 깊게 배우면서 이러한 생각을 해보았습니다.

JS도 프로토타입 기반 객체지향 언어인데 (클래스도 지원하는) 다중 상속을 할 수 있지 않을 까? 였습니다.

이 궁금증을 한번 해결해 보기 위해 다른 언어들과 비교하여 한번 다중 상속 코드를 작성 해보았습니다.

다른 언어의 다중 상속

파이썬

class Person:
  def greeting(self):
    print("안녕하세요.")

class University:
  def manage_credit(self):
    print("학점 관리")

class Undergraduate(Person, University):
  def study(self):
    print("공부하기")

jm = Undergraduate()
jm.greeting() # 안녕하세요
jm.manage_credit() # 학점 관리
jm.study() # 공부하기

Cpp

#include <iostream>
using namespace std;

class Person {
  public:
    void greeting() {
      cout << "안녕하세요" << endl;
    }
};

class University {
  public:
    void manage_credit() {
      cout << "학점 관리" << endl;
    }
};

class Undergraduate : public Person, public University {
  public:
    void study() {
      cout << "공부 하기" << endl;
    }
};

int main() {
  
  Undergraduate jm;
  jm.greeting(); // 안녕하세요
  jm.manage_credit(); // 학점 관리
  jm.study(); // 공부하기
  
  return 0;
}

JS 클래스 다중 상속 시도

JavaScript

class Person {
  greeting() { return "안녕하세요"; }
}

class University {
  manage_credit() { return "학점 관리"; }
}

class Undergraduate extends Person, University {
  study() { return "공부하기"; }
}

코드의 결과는...

위 사진에서 보는 것과 같이 콤마로 두 개의 클래스를 상속받으려고 하면 SyntaxError가 발생해 다중상속이 되지 않는 모습을 볼 수 있었습니다.

그렇다면 Class는 다중 상속이 안된다고 치고, 프로토타입으로는 다중상속이 가능한 지 한번 실험을 해보았습니다.

JS 프로토타입 다중 상속 시도

function Person() { }

Person.prototype.greeting = function () { return "안녕하세요"; }

function University() { }

University.prototype.manage_credit = function() { return "학점 관리"; }

function Undergraduate() { }

Undergraduate.prototype.study = function() { return "공부하기"; }

const me = new Undergraduate();


me.study(); // 공부하기
me.manage_credit(); // Uncaught TypeError me.manage_credit is not a function
me.greeting(); // Uncaught TypeError me.greeting is not a function

// 배열로 두 프로토타입을 동시에 프로토타입의 프로토타입 체인으로 연결한 경우

Undergraduate.prototype.__proto__ = [University.prototype, Person.prototype];

me.greeting(); // Uncaught TypeError: me.greeting is not a function

me[0].manage_credit(); // 학점 관리
me[1].greeting(); // 안녕하세요


// 프로토타입 체인으로 하나하나 연결한 경우
Undergraduate.prototype.__proto__ = University.prototype;
University.prototype.__proto__ = Person.prototype;


me.manage_credit(); // 학점관리
me.greeting(); // 안녕하세요

다음과 같이 배열로 한번에 프로토타입을 연결 시켜주게되면 기존 프로토타입처럼 참조할 수가 없기 때문에 프로토타입 체인끼리 연결 시켜주면 다중 상속을 한 것처럼 보이게 할 수는 있었습니다.

JS는 다중 상속을 할 수 없나?

결론부터 말씀드리면 그렇다고합니다.

자바스크립트는 단일 상속만을 허용하는 언어로, 객체엔 단 하나의 [[Prototype]]만 존재하며, 클래스는 클래스 하나만 상속받을 수 있습니다.

다중상속이 없는 경우, 다중상속을 사용하고 싶은경우 JS는 믹스인이라는 개념이 사용하면 도움이 될 것입니다.

믹스인

위키피디아에선 믹스인을 다른 클래스를 상속받을 필요없이 이들 클래스에 구현되어 있는 메서드를 담고 있는 클래스라고 정의합니다.

믹스인 예시

출처: https://ko.javascript.info/mixins

자바스크립트에서 믹스인을 구현할 수 있는 가장 쉬운 방법은 유용한 메서드 여러 개가 담긴 객체를 하나 만드는 것입니다. 이렇게 하면 다수의 메서드를 원하는 클래스의 프로토타입에 쉽게 병합할 수 있습니다.

아래 예시의 믹스인 sayHiMixinUser에게 '언어 능력’을 부여해줍니다.

// 믹스인
let sayHiMixin = {
  sayHi() {
    alert(`Hello ${this.name}`);
  },
  sayBye() {
    alert(`Bye ${this.name}`);
  }
};

// 사용법:
class User {
  constructor(name) {
    this.name = name;
  }
}

// 메서드 복사
Object.assign(User.prototype, sayHiMixin);

// 이제 User가 인사를 할 수 있습니다.
new User("Dude").sayHi(); // Hello Dude!

믹스인을 활용하면 User가 아래 예시처럼 다른 클래스를 상속받는 동시에, 믹스인에 구현된 추가 메서드도 사용할 수 있습니다.

class User extends Person {
  // ...
}

Object.assign(User.prototype, sayHiMixin);
profile
It is possible for ordinary people to choose to be extraordinary.

0개의 댓글