본문 바로가기
Javascript/Javascript 객체지향

[생활코딩] 객체지향 - super / 객체상속

by 닉우 2020. 8. 1.

<super>

class Person{
  constructor(name, first, second){
    this.name = name;
    this.first = first;
    this.second = second;
  }
  sum() {
    return this.first + this.second
  }
}

class PersonPlus extends Person{
  avg(){
    return (this.first + this.second)/2;
  }
}

var kim = new PersonPlus('kim',10 ,20);
console.log('kim.sum()', kim.sum());
console.log('kim.avg()', kim.avg());

 코드에서 아쉬운 부분이 있다.

PersonPlus 클래스에 first와 second 외에 third라는 세 번째 값도 갖고 싶을 때

기존의 값을 유지하면서 추가하기가 애매할것이다.

아래와같이 처리하면 상속을 쓰는 의미가 없어진다.

class Person{
  constructor(name, first, second){
    this.name = name;
    this.first = first;
    this.second = second;
  }
  sum() {
    return this.first + this.second
  }
}

class PersonPlus extends Person{
  constructor(name, first, second, third){
    this.name = name;
    this.first = first;
    this.second = second;
    this.third = third;
  }
  sum() {
    return this.first + this.second + this.third;
  }
  avg(){
    return (this.first + this.second + this.third)/3;
  }
}

 

이러한 경우를 위해서는 부모 클래스를 불러서 부모 클래스한테 일을 시키고

부모 클래스가 못하는 일을 나만 할 수 있게 하는게 super라는 키워드이다.

 

super는 두 가지 용법이 있다.

그 뒤에 괄호가 붙으면 걔는 부모 클래스의 생성자이다.

Person 클래스의 생성자가 호출이 되는거다.

 

super뒤에 . 이 붙으면 부모 클래스라고 생각하면 된다.

정리하자면 

super에 괄호가 있으면 부모클래스의 생성자,

괄호가 없으면 부모클래스 자체를 뜻한다.

만약 super라는 기능이 없으면, 자식클래스에서 부모클래스의 속성과 기능에

추가적인 무언가를 넣어 활용할때

다시 부모클래스의 코드를 사용해야하는 중복이 발생할 것이다.

 


객체지향 프로그램은 크게 두 가지로 나눠진다.

첫 번째는 객체를 만들어내는 공장, 설계도라고 할 수 있는 class 가 있고,

그 class를 통해서 만들어진 구체적인 객체가 있다.

이 두 가지의 요소들이 어떻게 상호작용 하느냐에 따라서 상당히 다른 형태의 객체지향 언어들이 만들어진다.

 

자바스크립트는 자바랑 정말 많이 다른 객체지향언어이다.

 

먼저, 주류 객제지향 언어(Java 등..)들의 상속에 대해서 살펴보면

sub class가 super class를 물려받기 위해서는 sub class가 자식이 돼야된다.

그렇게 만들어진 sub class를 통해서 객체를 생성해낸다. 그래서 그 객체가 어떤 기능을 할것인지는

class에서 결정되는거다.

물론 자바스크립트에서도 class와 extends라는 키워드가 있지만 이름이 같다고해서 주류 객체지향 언어와 내부적으로 동작하는 방법이 같지는 않다. 자바스크립트에서 타 언어를 사용하다 들어오는 사람들을 위해(?) 편하게 사용하라고 마련한 일종의 배려라고 생각하자. 생긴지 얼마 안됐다.

객체 자신이 다른 객체의 상속을 받는것은 불가능하다.

이 객체는 태어나면 자기가 어떤 기능을 가질것인지가 결정되어 있다.

 

자바스크립트의 상속주류 객체지향에 비해 매우 자유롭다.

기능을 추가하고 싶은 객체를 sub 객체라고 한다면,

sub 객체가 super 객체로부터 기능을 직접 상속받을 수가 있다.

주류 객체지향 언어에서는 class가 상속을 받지만, 자바스크립트에서는 객체가 직접 다른 객체의

상속을 받을 수가 있고, 얼마든지 상속관계를 바꿀수가 있다.

예를 들어 super객체에서 상속을 받았는데 필요에 의해서

다른 객체에서 상속을 받고 싶다면 링크만 바꾸어주면 된다. 그 링크를 prototype link라고 한다.

그리고 링크가 가리키고 있는 객체를 prototype object라고 부르는것이다.


<__proto__>

 

자바스크립트의 class문법이 아니라 전통적인 방법으로 상속하는 방법을 알아보자.

 

일단 생성자 객체가 아니라 그냥 객체로 만들어보자.

그리고 이 객체의 기본적인 값으로 superVal:'super' 를 주겠다.

현재 두 객체는 남남이다.

그런데 자바스크립트에서는 객체를 직접 다른 객체의 자식으로 만들수가 있다.

subObj의 원형이 무엇인가라는 것을 가리키는 프로토타입 링크를 정해주면 되는데,

그것을 하기 위해서는 다음과 같은 속성을 주고, 그 속성의 값으로 superObj를 준다.

 

'subObj.subVal => sub ' 이 출력된다.

subObj는 superVal이라는 값을 가지고 있지 않은데 super를 출력할수있다.

즉, __proto__ 프로토타입링크를 통해서 그 값을 가지고 온것이다.

subObj.superObj = 'sub';

이렇게 해주면 superObj의 값이 바뀔까?

'superObj.superVal => super ' 가 출력된다. 

안바뀐다. 왜냐면 superObj라는 값을 바꾼거지 __proto__가 가리키고 있는 객체를 바꾼게 아니다.

객체의 프로퍼티를 바꾸면 그 객체를 바꾸는거지 그 객체의 프로토를 바꾸는것이 아니다.

 

__proto__를 통해서 다른 객체를 상속받는 방법을 알아봤고,

__proto__의 값만 바꿔주면 그 순간에 그 객체는 다른 자식의 객체가 된다.(굉장히 유연함)

그 유연함으로 인해서 사고가 일어날 가능성이 높고 복잡성이 있다.

 

저 방법이 정석은 아니다.


<Object.create()>

 

__proto__ 대체제를 알아보겠다.

Object.create()를 통해서 객체와 객체간의 상속관계, 즉 명확하게 말하면 proto를 지정해주는 것이 좋다.

 

※ 만약에 subObj가 Object.create()를 사용했을때 어떤 변화를 겪게 되는지를 보고 싶다면,

   debugger 를 사용하면 자바스크립트의 실행을 일시중지 시킬수가 있고,

   우리가 객체 상태를 자세하게 들여다볼수있다.

개발자 도구에서 리로드하면 Sources라는 탭으로 바뀌면서 왼쪽에는 코드가 나오고,

debugger라는 코드에서 실행이 멈춰있다.

subObj 라고 하는 객체에는 어떤 프로퍼티가 있는지를 보고싶으면, Watch에 더하기 버튼을 눌러서  검색한다.

__proto__ 가 super를 가르키고 있다.


<객체상속의 사용>

 

var kim = {
  name: 'kim',
  first: 10, second: 20,
  sum: function() {return this.first + this.second}
}

console.log('kim.sum() : ', kim.sum());

이번에는 lee라는 객체를 만들때 sum()을 또 정의하기가 싫으면, 

프로토를 이용하면 된다.

lee 객체에 없으면 그 다음은 proto를 찾아본다. 

그리고 kim객체의 sum함수에 있는 this는 lee에서는 lee객체를 가리킨다.

 

lee에서만 사용할 수 있는 기능을 추가할 수도 있다.

이렇게 lee는 kim 가지고 있지 않은 기능도 가질수가 있다.

이제 __proto__보다 권장되는 방법인 Object.create()로 바꿔보자.

이렇게 권장되는 방법을 통해서 상속을 받을 수가 있다.


 

 

 

 

 

 

 

 

 

 

 

※ 본 포스팅은 개인 공부 기록을 목적으로 남긴 글이며 본 사실과 다른 부분이 있다면 과감하게 지적 부탁드립니다.

댓글