객체지향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}
- 아버지 class의 파라미터로 name='만수'가 들어간다.
- super('만수')로 인해 할아버지에 파라미터로 '만수'가 들어간다.
- 할아버지에 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을 물려받기 때문이다.

이건 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()를 실행시켜주세요** 라고 할 수 있다.
'Front-End: Web > JavaScript' 카테고리의 다른 글
[코딩애플] js part 2-8. class, extends, getter, setter 연습문제 (0) | 2022.10.21 |
---|---|
[코딩애플] js part 2-7. getter, setter 대체 왜 쓰는지 알아보기 (0) | 2022.10.21 |
[코딩애플] js part 2-5. ES6 방식으로 안쉽게 구현하는 상속기능(Class) (0) | 2022.10.21 |
[코딩애플] js part 2-4. 상속기능을 구현하는 다른 방법 (0) | 2022.10.21 |
[코딩애플] js part 2-3. Object 생성기계인 constructor를 만들어 써보자 (0) | 2022.10.21 |