※当方駆け出しエンジニアのため、間違っていることも多々あると思いますので、ご了承ください。また、間違いに気付いた方はご一報いただけると幸いです。
こちらは、
【JavaScript】クラス構文について 1
の記事の続きとなります。
##継承の構文
class 子クラス extends 親クラス {
}
継承することにより、親クラスの構造や機能を引き継ぐことができる。
子クラスから親クラスを呼び出す。
class Parent {
constructor(name) {
console.log(name);
}
}
// Parentを継承したChildクラスの定義
class Child extends Parent {
constructor(name) {
super(name); //superメソッドで親クラスのコンストラクタを呼び出す。
console.log(name);
}
}
const child = new Child("taro");
//taro 親コンストラクターが実行された結果
//taro 子コンストラクターが実行された結果
子クラスでコンストラクター関数を定義した場合、親コンストラクタ関数を上書き定義している。
子クラスでコンストラクターを定義しなかった場合は、当然親のメソッドを引き継いでいるので親のコンストラクタを子クラスは保持している。
class Parent {
constructor(name) {
console.log(name);
}
}
// Parentを継承したChildクラスの定義
class Child extends Parent {
//constructor(name) {
//console.log(name);
// } 親のコンストラクターを引き継いでいる。
}
const child = new Child("taro");
//taro 親コンストラクターが実行された結果
##プロトタイプ継承
親クラスが保持するメソッドは子クラスに引き継がれる。
class Parent {
say() {
console.log("oya");
}
}
class Child extends Parent {
//子クラスではsayメソッドを定義していない。
}
const instance = new Child();
instance.say();
//oya
これは、プロトタイプチェーンの仕組みにより、子クラスから親クラスへ引き継がれることになります。
プロトタイプチェーンについての詳細についてはこちらの記事をご覧ください。
一方クラスから、インスタンス生成時にもプロトタイプチェーンの仕組みを使ってインスタンスへメソッドが引き継がれます。(参照情報が渡される。)
乱暴な言い方をすると、javascriptでは、メソッドの引継ぎに関して、親クラスから子クラスへと、クラスからインスタンスへとでは同じ方法でメソッドを引き継いでるイメージとなります。
##superプロパティ
上記の通り、親クラスのメソッドは子クラスが引き継いでいるので、呼び出すことができます。しかし、同名のメソッドを子クラスで定義した場合、メソッドチェーンの仕組みから子クラスで定義したメソッドが呼び出されることになります。
class Parent {
say() {
console.log("oya");
}
}
class Child extends Parent {
say() { //親クラスと同名のメソッドを定義
console.log("ko");
}
}
const instance = new Child();
instance.say();
//ko
この時誤解してはいけないのは、sayメソッドは上書きされた訳では無いということです。
子クラスが親クラスを継承した時(メソッド定義前の段階)
class Parent {
prototype : {
say(){console.log("oya");};
}
}
//子クラスが親クラスを参照
class Child {
prototype : { //子クラスのプロトタイプオブジェクト
prototype : { //親クラスのプロトタイプオブジェクト(注:実体ではなく親クラスのプロトタイプオブジェクトのメモリ上の位置情報を格納)
say(){console.log("oya");};
}
}
}
この様に、子クラスのプロトタイプオブジェクトに、親クラスへのプロトタイプオブジェクトの参照情報が格納されます。
ここで、子クラスに同名のメソッドを定義した場合
class Child {
prototype : {
say(){console.log("ko");};//子クラスでsayメソッドを定義
prototype : {
say(){console.log("oya"); };//親クラスのsayメソッド
}
}
}
当然、スコープチェーンより、子クラスから生成したインスタンスからsayメソッドを呼び出すと、子クラスで定義したsayメソッドが呼び出されます。
const instance = new Child();
instance.say();
//ko
この場合、親クラスのsayメソッドをsuper.メソッド名で呼び出すことができます。
親クラスのコンストラクタを呼び出すには、上記の通り super(); メソッドを使いますが、親クラスのメソッドもsuper.メソッド名で呼び出すことができるのです。
class Child extends Parent {
say() {
console.log("ko");
}
parentSay() {
super.say(); //親クラスのsayメソッドを呼び出している。
}
}
const instance = new Child();
instance.parentSay();
//oya