객체지향에 대하여 어디선가 들은적이 있다. 객체는 세상의 모든 것을 표현하려고 만든 기법이라고,
세상 모든 기술, 학습, 지식, 역사는 전파, 전염,등... 여러 단어들로 이야기 할 수 있지만, 상속이라는 단어 하나로 통일도 될것이라 생각한다.
상속에 있어서 부모와 자식관계만이 있는 것은 아닐터... 부모도 자신들의 부모가 있을 것이고 '뿌리'부터 시작하여 지금까지 상속과 정제를 거쳐 세상이 순환하는지 모르겠다.
Class를 상속한 Class를 만들고 싶을 때 쓰는 extends
부모가 태초는 아니지 않겠는가?
부모의 부모 즉,
할아버지와 부모의 관계, 부모와 자식의 관계 할아버지와 손자의 관계등이 있을 터... 이것을 자바스크립트 언어로 풀어보자
class GrandPa {
constructor(name) {
this.firstName = 'Choi';
this.Name = name;
}
sayHi(){console.log('호호호')}
}
const grandFather = new grandPa('lulu');
// 이거랑 유사한 class, 즉 다시 말해 아버지 class를 만들고 싶다면
class Father extends GrandPa {
sayHi(){console.log('허허허')} // GrandPa의 메소드를 다시 재정의 할 수 있다. ='overriding'
}
const papaJhons = new Father('yuyu'); // father {firstName: 'Choi', Name: 'yuyu'}
papaJhons.sayHi()// '허허허'
이런 식으로 class를 상속한 class를 만들고 싶으면 extends keyword를 사용하면 될 뿐 아니라
grandPa의 class의 prototype의 메소드를
다시 재정의 'overriding'할 수 있다.
그런데 father Class에 새로운 속성을 추가 하고 싶으면??
당연히 father Class의 constructor안에 내용을 추가하면 됨
class GrandPa {
constructor(name) {
this.firstName = 'Choi';
this.Name = name;
}
}
const grandFather = new GrandPa('lulu');
// 이거랑 유사한 class, 즉 다시 말해 아버지 class를 만들고 싶다면
class Father extends GrandPa {
constructor() {
this.age = 30;
}
}
const papaJhons = new Father('yuyu');
이러면 될 줄 알았지만 에러가 빨갛게 난다.
Must call super constructor in derived .... 에러가 씨게 난다.. super라는 키워드를 넣으라고 하는데..
그럼 super를 넣어주면 된다.
super()라는 이상한 함수는
"extends로 상속중인 부모 class의 constructor()"를 의미함... (암기사항)
쉽게 말하면 할아버지 class의 constructor() 이거랑 똑같다는 소리입니다. (암기해야됨 하...)
그래야 이제 에러없이 this.나이 이런걸 추가하실 수 있다. (암기 ㄱ)
class GrandPa {
constructor(name) {
this.firstName = 'Choi';
this.Name = name;
}
}
const grandFather = new GrandPaa('lulu');
class Father extends GrandPa {
constructor() {
super()
this.age = 30;
}
}
const papaJhons = new Father('yuyu');
console.log(papaJhons);
// {firstName: 'Choi', Name: undefined, age: 30}
Name에서 undefined가 된다.
이유는
위의 설명처럼
class GrandPa {
constructor(name) {
this.firstName = 'Choi';
this.Name = name;
}
}
class Father extends GrandPa {
constructor() {
super()// super를 쓰면 아래와 같은 경우다.
this.age = 30;
}
}
//----------------------------------------
class Father extends GrandPa {
constructor(name) {
// constructor 아래의 것이 GrandPa의 constructor
constructor(name) {
this.firstName = 'Choi';
this.Name = name;
}
// Father의 값,
this.age = 30;
}
}
// -------------------------------------------
class Father extends GrandPa {
constructor(name,number) {
super(name)// GrandPa의 constructor, name값
this.age = number;// Father의 파라미터 값
}
}
위 코드처럼 GrandPa class의 constructor()에는 name 파라미터를 넣어줘서 Name: undefined
가 떴던 이유이다.
그러므로
똑같이 따라서 명시해줘야 GrandPa가 가진 모든 속성들을 정확히 상속받을 수 있다.
함수 상속을 하고 싶으면 super를 쓰면 된다.
super.함수명()
써주자class GrandPa {
constructor(name) {
this.firstName = 'Choi';
this.Name = name;
}
sayHi(){console.log('허허허')}// 1- prototype에 함수쓰기
}
-----------------
class Father extends GrandPa {
constructor(name,number) {
super(name)
this.age = number;
}
func(){
// 2- super.함수명() 호출
super.sayHi()
/*
super.sayHi() = GrandPa.prototype.sayHi와 비슷함
단 !! 상속해주는 Class (GrandPa)의 메소드를 사용 하고 싶으면
prototype(=GrandPa,Father 둘다)에서만 사용가능
*/
}
super.sayHi() // 이렇게 못씀 !!!
}
const father = new Father('luna',30);
// {firstName: 'Choi', Name: 'luna', age: 30}
// Name값은 GrandPa의 파라미터, age 값은 Father의 파라미터
father.func()// '허허허'