4.1 継承は簡単
継承は、オブジェクト指向プログラミング (OOP) の基本的な概念で、1つのクラス(サブクラスまたは子クラスと呼ばれる)が 別のクラス(スーパークラスまたは親クラスと呼ばれる)のフィールドとメソッドを継承することを可能にするものだよ。
このアプローチを使うと、より汎用的なクラスを作成してコードを再利用できるようになり、コードの組織化と保守が改善されるんだ。
なんで継承が必要なの?
コードを書く必要があるときに、クラスとして書くことにしたとしよう。でもプロジェクトにはすでに ほとんど必要なことをするクラスがあることがわかった。そこで、そのクラスのコードをそのまま コピーして使うこともできるよね。
でも「コピーしたふり」をすることもできる。そのクラスを自分のクラスの親と宣言すると、 JavaScript が親クラスの動作をあなたのクラスに追加してくれるんだ。
例えば、自分が大自然で犬を作りたいとする。細菌から犬を1億年かけて作るのと、 狼を20万年で家畜化するの、どっちが速いと思う?
4.2 プロトタイプ継承の概念
JavaScriptのプロトタイプ継承は、オブジェクトが他のオブジェクトからプロパティとメソッドを 継承するための主要なメカニズムの一つ。これにより、複雑なオブジェクトの階層を作成して、コードを再利用できるんだ。
JavaScriptの各オブジェクトは隠しプロパティ[[Prototype]]を持っていて、それがそのプロトタイプを指している。 プロトタイプは継承を実装するために使用され、オブジェクトが他のオブジェクトからプロパティとメソッドを継承できるようになるんだ。
シンプルな継承の例
ステップ1: 基本的なオブジェクトの作成
const animal = {
eat() {
console.log('Eating...');
},
sleep() {
console.log('Sleeping...');
}
};
ステップ2: 子オブジェクトの作成
const dog = Object.create(animal);
dog.bark = function() {
console.log('Barking...');
};
ステップ3: 継承されたプロパティとメソッドの利用
dog.eat(); // 出力される: Eating...
dog.sleep(); // 出力される: Sleeping...
dog.bark(); // 出力される: Barking...
この例では、dog
オブジェクトがanimal
オブジェクトからeat()
とsleep()
メソッドを継承し、
自分自身のメソッド―bark()
を追加しているよ。
4.3 プロトタイプを使った深い継承
プロトタイプチェーン
JavaScriptでは、オブジェクトが互いに継承し合ってプロトタイプチェーンを形成することで、より複雑な継承が可能になるんだ。
プロトタイプチェーンの例
この例では、dog
オブジェクトがmammal
から継承し、さらにmammal
がanimal
から継承している。
これにより、dog
はmammal
とanimal
のすべてのメソッドにアクセスできるプロトタイプチェーンを作成しているんだ。
const animal = {
eat() {
console.log('Eating...');
}
};
const mammal = Object.create(animal);
mammal.walk = function() {
console.log('Walking...');
};
const dog = Object.create(mammal);
dog.bark = function() {
console.log('Barking...');
};
dog.eat(); // 出力される: Eating...
dog.walk(); // 出力される: Walking...
dog.bark(); // 出力される: Barking...
プロトタイプチェーンの確認
isPrototypeOf()
メソッドを使うと、あるオブジェクトが他のオブジェクトのプロトタイプかどうかを確認できるよ。
例:
console.log(animal.isPrototypeOf(mammal)); // 出力される: true
console.log(mammal.isPrototypeOf(dog)); // 出力される: true
console.log(animal.isPrototypeOf(dog)); // 出力される: true
4.4 メソッドのオーバーライド
プロトタイプによる継承は、新しいメソッドを追加できるだけでなく、既存のメソッドをオーバーライド(上書き)することも可能だよ。
メソッドのオーバーライド例
この例では、dog
オブジェクトのspeak()
メソッドがanimal
オブジェクトのspeak()
メソッドをオーバーライドしているんだ。
const animal = {
speak() {
console.log('Animal speaks');
}
};
const dog = Object.create(animal);
dog.speak = function() {
console.log('Dog barks');
};
animal.speak(); // 出力される: Animal speaks
dog.speak(); // 出力される: Dog barks
親オブジェクトのメソッドを呼び出す
JavaScriptで親オブジェクトのメソッドを呼び出すには、call()
やapply()
メソッドを使うことができるよ。
例:
const animal = {
speak() {
console.log('Animal speaks');
}
};
const dog = Object.create(animal);
dog.speak = function() {
animal.speak.call(this);
console.log('Dog barks');
};
dog.speak();
// 出力される:
// Animal speaks
// Dog barks
4.5 プロトタイプ継承の深い活用
組み込みオブジェクトの拡張
JavaScriptの組み込みオブジェクトを拡張し、そのプロトタイプにメソッドを追加することができるよ。
例:
Array.prototype.sum = function() {
return this.reduce((acc, value) => acc + value, 0);
};
const numbers = [1, 2, 3, 4, 5];
console.log(numbers.sum()); // 出力される: 15
多層階の階層の作成
プロトタイプ継承を使用して、より複雑な多層階のオブジェクト階層を作成することができるよ。
例:
const livingBeing = {
breathe() {
console.log('Breathing...');
}
};
const animal = Object.create(livingBeing);
animal.eat = function() {
console.log('Eating...');
};
const mammal = Object.create(animal);
mammal.walk = function() {
console.log('Walking...');
};
const dog = Object.create(mammal);
dog.bark = function() {
console.log('Barking...');
};
dog.breathe(); // 出力される: Breathing...
dog.eat(); // 出力される: Eating...
dog.walk(); // 出力される: Walking...
dog.bark(); // 出力される: Barking...
GO TO FULL VERSION