본문 바로가기
  • think normal
새로워지기/서른의 생활코딩

[생활코딩 따라가기] javascript 객체 지향 프로그래밍_10.super

by 청춘만화 2019. 4. 30.

javascript 객체 지향 프로그래밍

생코 수업 Link : https://opentutorials.org/module/4047/24620 

 

super - JavaScript 객체 지향 프로그래밍

수업소개 서브(자식) 클래스에서 상위 클래스를 호출할 때 사용하는 super 키워드를 소개합니다.  강의 코드 class.js (변경사항) class Person{ constructor(name, first, second){ this.name = name; this.first = first; this.second = second; } sum(){ return this.first+this.second; } } class PersonPlus extends P

opentutorials.org

 

10. super

1. 학습 목표 이해하기 

아래 코드에서 ' var kim = new PersonPlus('kim',10,20,30); '와 같이 부모만 가지고 있는 기능을 수정하고자 하는 경우?는 어떻게 해야할까?

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{  
    arg(){  
        return " 평균 : "+(this.first+this.second)/2;
    }
}

var kim = new PersonPlus('kim',10,20,30); // 상속받은 클래스에 있는 생성자에 인자를 추가하고 싶은 경우 

console.log(kim.name, " 's sum : ",kim.sum());   
console.log(kim.name, " 's arg : ",kim.arg());   

 

2. 해결방안 모색

2-1) 가장 쉬운? 원초적인 해결 방법

자식 클래스에도 똑같이 생성자를 추가하고 수정하는 방법이다. 하지만 이렇게 되면 앞서 상속을 받지 않은 경우와 동일한 상황이 발생한다. 

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); 
    }
    arg(){  
        return " 평균 : "+(this.first+this.second+this.third)/3;
    }
}

var kim = new PersonPlus('kim',10,20,30); // 상속받은 클래스에 있는 생성자에 인자를 추가하고 싶은 경우 

console.log(kim.name, " 's sum : ",kim.sum());   
console.log(kim.name, " 's arg : ",kim.arg());   

 

참고로) 위의 코드는 실행되지 않는다. 에러 메시지는 다음과 같다.

ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor.

영알못인 입장에서.. 다음을 해석하자면, 자신의 클래스 생성자가 this에 접근하거나, 반환되기 전에 먼저 부모의 생성자, super를 반드시 먼저 호출해야 한다. 라고 하는 것 같은 느낌적인 느낌의 메시지이다. 

 

참고로 X2) JAVA에서 유사한 내용이 있어 링크를 남겨둔다.

http://blog.naver.com/PostView.nhn?blogId=dho113&logNo=220569294749&parentCategoryNo=29&categoryNo=&viewDate=&isShowPopularPosts=true&from=search

 

[JAVA] 상속관계 생성자 호출 순서

상속관계에서는 객체 생성시 슈퍼클래스의 생성자도 호출한다는 점! 간단한 예로 호출순서와 실행 순서를 ...

blog.naver.com

 

2-2) 조금 더 근본적인 해결방법

super.js)

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{  
    constructor(name,first,second,third){
        super(name,first,second), //super(인자들) = 부모 클래스의 constructor(인자들)
        this.third = third
    }

    sum(){    
        return " 합계 : "+(this.first+this.second+this.third);  
        //super.sum()을 쓰지않고 직접 기입한 예 
    }
    arg(){  
        return " 평균 : "+(super.sum()+this.third)/3;
        //super.sum() = 부모 클래스가 보유한 메서드 호출한 예 
        // * super.sum = 부모 클래스가 보유한 메서드 내용을 그대로 출력
    }
}

var kim = new PersonPlus('kim',10,20,30); // 상속받은 클래스에 있는 생성자에 인자를 추가하고 싶은 경우 

console.log(kim.name, " 's sum : ",kim.sum());   
console.log(kim.name, " 's arg : ",kim.arg());   

실행 결과)

super 메소드 활용 결과

 

 

 

 3. 한번 더 생각해보기

egoing의 질문1. super의 용법 두가지, ()가 있을 때와 없을 때의 차이는 
-> my : 1) super()는 부모 클래스의 생성자와 동일한 역할을 수행한다. 따라서 부모 클래스 생성자가 a,b라는 인자를 가지고 있다면 super(a,b)로 표현할 수 있다. 2) super는 '부모 클래스 입장에서의 this'와 같다고 볼 수 있을 것 같다.  예컨데 this가 my라면, super는 his/her/their로 해석할 수 있지 않을까? 생각한다. 따라서 본 예제에서의 super.sum() 는 부모의sum()메소드, 다시말해 their sum() 정도로 해석할 수 있지 않을까 한다.

 

egoing의 질문2. super 편리함은(상속으로 인한 단점을 어떻게 개선하는지 등)?
-> my : 부모의 속성을 물려 받긴 하겠는데 그대로 물려받아 사용하기는 애매하고, 그 속성의 일부를 수정해야 할 때 사용된다. 이런 경우 super를 사용하지 않으면, 부모의 속성과 10개 중 9개가 같고 1개만 다르더라도 10개 모두를 새로 생성해야 한다. 이를테면 아버지의 운전자 보험에 자식을 포함시키면 돈을 조금만 내면 되는데... 자식이 신규로 가입하면 많은 비용이 지출되는 것과 같다고 할까? ㅋㅋㅋ 
참고로 이 경우 extends를 할 수 없다. Must call super constructor in derived class 에러가 난다. extends하는 경우 부모의 생성자가 먼저 호출되기 때문인 것 같다. 다시말해 그냥 새로운 클래스를 선언하는 상황이 발생하는 것이다. 

댓글