본문 바로가기

플밍 is 뭔들/JavaScript&jQuery

[JavaScript] 자바스크립트 객체지향 프로그래밍 - 상속

※ 상속이란?

부모 클래스의 속성과 메서드를 자식 클래스가 물려받는 것.
상속을 받은 자식 클래스는 부모 클래스의 속성과 메서드를 사용할 수 있고 필요한 기능을 추가해 확장할 수 있다.

※ 상속의 기능
    
    코드의 복사 없이 자식클래스는 부모 클래스의 기능과 속성을 사용 가능하므로 다음과 같은 기능을 가질 수 있다.
  1. 코드 재사용
  2. 중복 코드 제거
  3. 확장성

※ 자바스크립트에서 클래스 상속

자바스크립트에서는 객체지향 프로그래밍 특징 네 가지 중 유일하게 클래스 상속을 지원한다.
자바스크립트 상속은 프로토타입을 이용해 구현한다.

function 부모클래스(){
    this.프로퍼티 = 값;
}

부모클래스.prototype.method = function(){
    //기능구현
}

function 자식클래스(){}

//상속
자식클래스.prototype = new 부모클래스();



※ 자식 클래스에서 부모 클래스의 생성자 호출

상속 구현 시 부모 클래스의 생성자에 매개변수가 있는 경우 자식 클래스에서 부모 클래스의 생성자를 호출해 매개변수 값을 전달해야 한다. 이때 부모 클래스의 생성자를 호출할 때 함수객체에서 제공하는 call() 메서드를 이용해 첫 번째 매개변수에 자식 인스턴스를 전달하고 두번째 매개변수 이후에는 부모의 생성자로 전달할 데이터를 전달한다.

문법)
function 자식클래스 ([param1, param2, ...]){
    부모클래스.call(this , [param1, param2, ...])
}

ex)
function Parent(param1){

    //부모 생성자
    this.property1 = param1;
}

Parent.prototype.method1 = function(){ alert(this.property1) }

function Child(param1){

    //자식 함수 생성자... 부모 생성자 호출 [this = 자식 인스턴스 / param1 = 부모 생성자에 전달할 데이터]
    Parent.call(this, param1);
}

//상속받기
Child.prototype = new Parent();

//생성자 설정
//아래 구문을 호출해 주지 않으면 부모에 값이 전달되지 않아 method1()을 호출 할 때 정상적인 값이 나오지 않는다.
Child.prototype.constructor = Child;
/*
  일반적으로 클래스를 만들면 prototype의 contructor라는 프로퍼티가 생성된다.
  이 프로퍼티에는 해당 클래스의 생성자 정보가 기본값으로 담기게 된다.
  즉 constructor프로퍼티를 이용해 어떤 클래스의 인스턴스인지 알아낼 수 있다.
  하지만 상속관계시 contructor프로퍼티에는 부모 클래스의 생성자가 담기게 된다
  그렇기 때문에 아래 Child.prototype.constructor에 자식 클래스의 생성자를 담아주지 않으면 method1() 호출시
  값이 정상적으로 나오지 않을 수 있다.
  실무에서는 constructor를 가지고 어떤 클래스의 인스턴스인지 비교할 일이 많지는 않지만 개인 라이브러리를 만들 때
  유용하게 사용된다고 한다.
*/ 

$(document).ready(function(){
    //자식 클래스 인스턴스 생성
    var child = new Child("data");

    //상속받은 함수 호출
    child.method1();
})



※ 자바스크립트에서의 오버라이드

 - 오버라이드란?
자식 클래스에서 부모 클래스의 기능을 재정의할 때 사용하는 기능
주로 부모 클래스에서 기능을 사용하지 않고 자식 클래스에서 구현한 기능을 사용하고 싶을때, 부모 클래스의 기능을 자식클래스에서 확장하고 싶은경우 사용한다.
문법)
method1()은 부모 클래스에 정의된 메서드이다. 

Parent.prototype.method1 = function(){}
Child.prototype.method1 = function(){}

**오버라이드 하고자 하는 기능을 자식클래스에서 똑같은 이름으로 만들어주면 된다.
그렇게 되면 부모 클래스에서 직접 수정하지 않아도 자식 클래스에서 자식에게 맞게 메서드를 재정의해 사용가능하다.



※ 부모 클래스의 기능을 자식 클래스에서 확장

위의 오버라이드는 부모 클래스의 기능을 자식 클래스에서 새롭게 재정의 해서 사용하는 것이었다. 하지만 부모의 기능을 완전히 새롭게 재정의 하는게 아니라 부모의 기능을 그대로 사용하면서 기능을 약간 추가해야할 때는 어떻게 해야 할까?
이럴때도 오버라이드를 활용한다.
기본은 오버라이드하고자 하는 부모 클래스의 기능(메서드)을 자식 클래스에서 동일한 이름으로 만들어 주는 것이다.
그런 다음 call() 메서드를 이용해 부모의 기능을 호출해 준다. 그 다음 추가하고자 하는 구문을 작성한다.
문법)
method1()은 부모 클래스에 정의된 메서드이다.

자식클래스.prototype.method1 = function([param1, param2, ...]){

    //부모클래스 메서드 호출
    부모클래스.prototype.method1.call(this, [param1,param2,...])

    //확장할 기능을 구현
    ...
    ...
}



※ 자바스크립트에서 메서드 오버로딩

오버로딩은 동일한 이름을 가진 여러 개의 메서드를 만든 후 매개변수 타입과 개수에 맞는 메서드가 자동으로 호출되는 기능이다.
하지만 자바스크립트는 오버로딩 기능을 지원하지 않는다. 대신 매개변수 정보를 담고있는 arguments를 이용해 오버로딩을 흉내낼 수는 있다.
ex)

function sum(){
    var result = 0;
    for(var i =0 ; i<arguments.length ; i++){
        result = result + arguments[i];
    }
}


sum(10,20);
sum(10,20,30);
sum(10,20,30,40);



※ 클래스 상속 규칙

상속을 하면 부모의 기능을 재사용할 수 있고 기능을 재정의해 확장도 할 수 있다. 하지만 클래스 상속은 아무때나 사용해서는 안된다.
반드시 상속관계가 성립될 때만 사용해야 한다.

코드 재사용만을 위해, 중복 코드 제거만을 위해 클래스 상속을 사용해선 안된다.
패밀리관계(IS A)를 유지하면서 기능을 확장할 때만 사용해야 한다.

IS A 공식 = 자식은 부모이다 
ex) 슈퍼맨(자식클래스)은 사람(부모클래스)이다. (O)
      강아지(자식클래스)는 사람(부모클래스)이다. (X)

      강아지도 사람이 갖고있는 기능(먹다,보다 등등...)을 가지고 있지만 상속 규칙에 어긋나므로 상속을 해서는 안된다.