본문 바로가기

Front-End: Web/JavaScript

[코딩애플] js part 2-6. class를 복사하는 extends / super

반응형

객체지향5. class를 복사하는 extends / super

부모와 유사한 class를 하나 더 만들고 싶다면? ➡️ extends (class 상속)

class 부모 { ... }

class 하나 만들기

class 할아버지{
	constructor(name){
        this.성 = 'Kim';
        this.이름 = name;
    }
}

var 할아버지1 = new 할아버지('만덕');
// 할아버지1 == 할아버지 {성: 'Kim', 이름: '만덕'}

이거랑 유사한 class를 만들고 싶다면(할아버지의 속성들 그대로 물려받아서)

class 아버지 extends 할아버지 {
	constructor (){
        this.나이 = 50;
    }
}

var 아버지1 = new 아버지(); // Uncaught ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derivced constructor at new 아버지

에러가 발생한다. 왜냐하면 할아버지의 속성들을 모두 물려받은, **extends 해서 만든 class는 this를 그냥은 못쓰기 때문**이다. **this를 써서 더 추가하고 싶다면 super() 함수 다음에 써야한다.**

super(): 물려받는 class의 constructor

class 아버지 extends 할아버지 {
	constructor (){
        super(); // ⬅️
        this.나이 = 50;
    }
}
class 아버지 extends 할아버지 {
	constructor (){
        this.성 = 'Kim'; // ⬅️
        this.이름 = name; // ⬅️
        this.나이 = 50;
    }
}

super()는 위와 같다. 엄밀히 말하면 할아버지에 있는 내용을 그대로 아버지에 갖다 붙이세요 라는 의미다.

근데 지금 name은 없다. 그래서 할아버지에 작성된 파라미터를 똑같이 명시해주어야 한다.

class 아버지 extends 할아버지 {
	constructor (name){ ⬅️
        super(name); ⬅️
        this.나이 = 50;
    }
}

이제 출력해보자.

var 아버지1 = new 아버지(); // 아버지 {성: 'Kim', 이름: undefined, 나이: 50}

이름은 파라미터를 받아서 집어넣겠다고 해놓았는데, 아버지1 오브젝트를 만들 때 아무 파라미터도 안넣고 만들었기 때문에 undefined라 뜬다.

var 아버지1 = new 아버지('만수'); // 아버지 {성: 'Kim', 이름: '만수', 나이: 50}
  1. 아버지 class의 파라미터로 name='만수'가 들어간다.
  2. super('만수')로 인해 할아버지에 파라미터로 '만수'가 들어간다.
  3. 할아버지에 this.이름 = '만수'로 지정된다.

이렇게 class를 extends해서 class를 새로 만들 수 있다.

만약 super() 파라미터 자리에 아무것도 넣지 않았다면? 할아버지가 파라미터를 받지 못해서 undefined가 뜬다.

class 아버지 extends 할아버지 {
	constructor (name){ ⬅️
        super();
        this.나이 = 50;
    }
}
var 아버지 = new 아버지('만수'); // 아버지 {성: 'Kim', 이름: undefined, 나이: 50}

파라미터가 2개 이상이면?

class 할아버지{
	constructor(name, name2){ ⬅️
        this.성 = 'Kim';
        this.이름 = name;
        this.이름2 = name2;
    }
}

class 아버지 extends 할아버지 {
	constructor (name, name2){ ⬅️
        super();
        this.나이 = 50;
    }
}
var 아버지 = new 아버지('만수');

똑같이 맞춰서 작성해주면 된다.

super()의 또 다른 용도: 부모 class의 prototype 가져다쓰기 가능

할아버지 class에 sayHi 함수를 추가해보자.

class 할아버지{
	constructor(name, name2){
        this.성 = 'Kim';
        this.이름 = name; 
    }
    sayHi(){
        console.log('안녕'); // 할아버지.prototype에 추가됨
    }
}

class 아버지 extends 할아버지 {
	constructor (name){
        super(name);
        this.나이 = 50;
    }
}
var 아버지1 = new 아버지('만수');
console.log(아버지1.sayHi()); // 안녕

그러면 아버지1은 sayHi()함수를 쓸 수 있다. 왜냐하면 아버지의 부모(할아버지)의 prototype을 물려받기 때문이다.

![](.\images\13.png)

이건 super와 상관없이 무조건 상속할 수 있다!!

근데 만약 아버지 class에 sayHi를 또 추가했다면?

class 할아버지{
	constructor(name, name2){
        this.성 = 'Kim';
        this.이름 = name; 
    }
    sayHi(){
        console.log('안녕 저는 할아버지예요');
    }
}

class 아버지 extends 할아버지 {
	constructor (name){
        super(name);
        this.나이 = 50;
    }
    sayHi(){ // ⬅️
        console.log('안녕 저는 아버지예요');
    }
}
var 아버지1 = new 아버지('만수');
console.log(아버지1.sayHi()); // 안녕 저는 아버지예요

왜냐하면 나와 좀 더 가까운 prototype에 있는 애를 먼저 출력시켜주기 때문이다.

근데 그 안에서 super를 쓸 수 있다.

class 아버지 extends 할아버지 {
	constructor (name){
        super(name); // ⬅️ 부모 class의 constructor를 의미
        this.나이 = 50;
    }
    sayHi(){
        console.log('안녕 저는 아버지예요');
        super.sayHi(); // ⬅️ ==prototype.sayHi(). 부모 class의 prototype을 의미
    }
}
console.log(아버지1.sayHi());
// 안녕 저는 아버지에요
// 안녕 저는 할아버지에요

이렇게 **부모 prototype에 각인되어 있는 sayHi()를 실행시켜주세요** 라고 할 수 있다.

반응형