[자바스크립트]클래스(class) [3] -extends / super
extends
class를 상속한 class를 만들고 싶을 때 쓰는 extends
할아버지 class를 하나 만들고 할아버지 class는 성과 이름이라는 속성을 가지고 있습니다.
class 할아버지{
constructor(name){
this.성 = 'Kim';
this.이름 = name;
}
}
그럼 이제 new 할아버지() 이렇게 하면 새로운 object를 쉽게 생성할 수 있습니다
그런데 이 class가 너무나도 유용한 나머지 이것과 유사한 class를 하나 더 만들고 싶습니다.
그러면 직접 class를 하나 더 만들어서 내용을 복붙하면 되겠죠?
하지만 class안에 복사할 내용이 너무나도 많으면 코드가 너무나도 길어집니다.
extends라는 문법을 이용해서 class를 만드시면 기존에 있던 class의 내용을 그대로 복붙해서 만들어낼 수 있습니다.
있어보이게 말하면 "다른 class를 상속해서 만들 수 있게 도와주는 문법"이죠.
(extends 사용방법)
class 할아버지{
constructor(name){
this.성 = 'Kim';
this.이름 = name;
}
}
class 아버지 extends 할아버지{
}
할아버지라는 class를 그대로 복붙한 아버지라는 class가 생성됩니다.
new 아버지(); 이렇게 테스트 해보면 class가 복제가 됩니다
new 아버지('만수'); 이렇게 하시면 성과 이름을 가진 object 자료가 하나 생성됩니다.
아버지라는 class에는 새로운 속성을 추가하고 싶으면 ?
아버지 constructor안에 내용을 추가하시면 됩니다.
class 할아버지{
constructor(name){
this.성 = 'Kim';
this.이름 = name;
}
}
class 아버지 extends 할아버지{
constructor(){
this.나이 = 50;
}
}
이렇게 하면 new 아버지() 했을 때 생성된 오브젝트들은 {성, 이름, 나이} 속성들을 가지겠군요.
하지만 이러면 에러가 납니다.
여기서 ! super를 써야 합니다!
super
class 할아버지{
constructor(name){
this.성 = 'Kim';
this.이름 = name;
}
}
class 아버지 extends 할아버지{
constructor(){
super();
this.나이 = 50;
}
}
super()라는 함수는"extends로 상속중인 부모 class의 constructor()"를 의미합니다.
쉽게 말하면 할아버지 class의 constructor() 이거랑 똑같다는 소리입니다.
그래야 이제 에러없이 this.나이 이런걸 추가하실 수 있습니다
근데 할아버지 class의 constructor()에는 name 파라미터를 입력할 수 있었죠?
그것도 똑같이 따라서 명시해주셔야 할아버지가 가진 모든 속성들을 정확히 상속받을 수 있습니다.
class 할아버지{
constructor(name){
this.성 = 'Kim';
this.이름 = name;
}
}
class 아버지 extends 할아버지{
constructor(name){
super(name);
this.나이 = 50;
}
}
할아버지 constructor()에 name이라는 파라미터가 있던걸 그대로 아버지 constructor()에도 따라했습니다.
(파라미터 작명은 자유롭게 가능합니다)
이제 그럼 new 아버지(); 할 때 파라미터를 입력하면 this.이름 속성에 들어가게 되겠네요.
그럼 예상해봅시다.
Q. 위 코드 하단에 var a = new 아버지('만수'); 이렇게 적으면 a라는 변수는 어떤 내용을 가지고 있을까요?
1. a라는 변수는 아버지라는 class로부터 새로 생성된 오브젝트입니다.
2. 그래서 할아버지가 가지고 있던 성, 이름 그리고 아버지가 가지고 있던 나이를 전부 물려받았습니다.
3. 그리고 this.이름 자리에는 '만수'를 넣어 실행했습니다.
그래서 { 성 : 'Kim', 이름 : '만수', 나이 : 50 } 이라는 오브젝트가 됩니다.
할아버지에 메소드(함수)를 추가한다면
할아버지 class 안에 함수를 추가한다면 아버지 class의 자식들도 물려받아 쓸 수 있을까요?
class 할아버지{
constructor(name){
this.성 = 'Kim';
this.이름 = name;
}
sayHi(){
console.log('안녕 나는 할아버지')
}
}
class 아버지 extends 할아버지{
constructor(name){
super(name);
this.나이 = 50;
}
}
var a = new 아버지('만수');
그럼 이제 a라는 오브젝트는 sayHi()라는 함수를 쓸 수 있을까요?
- 쓸 수 있습니다.
a라는 오브젝트가 a.sayHi() 이렇게 사용한다면
1. a라는 오브젝트에 sayHi가 있는지 물어보고
2. 없으면 아버지.prototype에 sayHi가 있는지 물어보고
3. 없으면 할아버지.prototype에 sayHi가 있는지 물어보고
이런 식으로 sayHi를 실행하기 위해 부모님을 뒤져봅니다.
근데 sayHi()라는건 할아버지.prototype에 추가된 함수이기 때문에
a라는 오브젝트는 sayHi() 함수를 실행할 수 있습니다.
근데 class간에 함수를 상속하고 싶으면 어떻게 해요?
뭔소리냐면.. 아버지라는 class에 함수를 만들고 싶습니다.
근데 할아버지 class에 있던 sayHi()라는 함수가 너무나도 유용한 나머지
이걸 그대로 아버지 class에 가져와서 활용하고 싶은 것입니다.
그럴 때 어떻게 합니까?
이 때도 super를 쓰시면 됩니다.
class 할아버지{
constructor(name){
this.성 = 'Kim';
this.이름 = name;
}
sayHi(){
console.log('안녕 나는 할아버지')
}
}
class 아버지 extends 할아버지{
constructor(name){
super(name);
this.나이 = 50;
}
sayHi2(){
console.log('안녕 나는 아버지');
super.sayHi();
}
}
var a = new 아버지('만수');
super라는걸 저렇게 prototype 함수 안에서 쓰시면 아까의 super와 약간 다른 의미가 됩니다.
여기서의 super는 부모 class의 prototype을 의미합니다.
uper는 뜻이 두개입니다.
1. constructor 안에서 쓰면 부모 class의 constructor
2. prototype 함수 안에서 쓰면 부모 class의 prototype
입니다. 아이고 외우기 힘드니까 2번은 참고로만 알아둡시다.
Q. 그럼 위의 예제 코드에서 a.sayHi2()를 실행하면 무엇이 콘솔창에 출력될까요?
a.sayHi2()를 사용하신다면 아버지.prototype에 있던 sayHi2 함수가 동작합니다.
그 함수는 일단 console.log('안녕 나는 아버지')를 실행하고
둘째 줄에서 super.sayHi()를 실행합니다. 이건 다른말로 할아버지.prototype.sayHi()와 똑같기 때문에
console.log('안녕 나는 할아버지')를 실행할 것입니다.
그래서 콘솔창에 "안녕 나는 아버지" "안녕 나는 할아버지"가 출력됩니다.
a.sayHi2()를 사용하신다면 아버지.prototype에 있던 sayHi2 함수가 동작합니다.
그 함수는 일단 console.log('안녕 나는 아버지')를 실행하고
둘째 줄에서 super.sayHi()를 실행합니다. 이건 다른말로 할아버지.prototype.sayHi()와 똑같기 때문에
console.log('안녕 나는 할아버지')를 실행할 것입니다.
그래서 콘솔창에 "안녕 나는 아버지" "안녕 나는 할아버지"가 출력됩니다.