継承の基本
CoddyのPHPジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 21/91。
継承を使用すると、あるクラスが別のクラスからプロパティやメソッドを引き継ぐことができます。同じコードを何度も書き直す代わりに、共有機能を持つベースクラスを作成し、他のクラスにそれを継承させることができます。
継承元のクラスは親クラス(またはベースクラス)と呼ばれ、継承する側のクラスは子クラスと呼ばれます。この関係を構築するには、extendsキーワードを使用します:
<?php
class Animal {
public $name;
public function __construct($name) {
this->name = $name;
}
public function speak() {
return "$this->name makes a sound";
}
}
class Dog extends Animal {
public function fetch() {
return "$this->name fetches the ball";
}
}
$dog = new Dog("Buddy");
echo $dog->speak() . "\n";
echo $dog->fetch();
出力:
Buddy makes a sound
Buddy fetches the ballDogクラスは、Animalの$nameプロパティ、コンストラクタ、およびspeak()メソッドに自動的にアクセスできます。また、犬だけが持つ独自のfetch()メソッドも定義しています。
これにより、明確な階層構造が作成されます。すべての犬は動物であるため、Dog が Animal を継承するのは理にかなっています。子クラスは、親クラスのすべてを利用しつつ、独自の特化した振る舞いを追加することができます。
重要なポイント: 継承はコードの再利用を促進し、クラス間の論理的な関係を確立します。子クラスは親からすべての public および protected メンバを継承するため、重複が減り、コードの保守が容易になります。
チャレンジ
簡単継承によって、子クラスが親クラスの機能を共有しながら、独自の特化した動作を追加できることを示す車両階層システムを構築しましょう。
コードを3つのファイルに分けて構成します:
Vehicle.php— すべての車両の親となるVehicleクラスを定義します。パブリックな$brandプロパティと、ブランドを受け取って設定するコンストラクタを持たせる必要があります。"[brand] is starting"を返すstart()メソッドと、"[brand] is stopping"を返すstop()メソッドを含めてください。Motorcycle.php—Vehicleを継承するMotorcycleクラスを定義します。ファイルの先頭で Vehicle ファイルをインクルードしてください。Motorcycleクラスは親のコンストラクタを継承するため、独自のコンストラクタは必要ありません。オートバイ特有の動作として、"[brand] is doing a wheelie!"を返すwheelie()メソッドを追加してください。main.php— Motorcycle ファイル(すでに Vehicle をインクルードしています)をインクルードします。入力としてオートバイのブランドを1つ受け取ります。このブランドを使用してMotorcycleオブジェクトを作成してください。start()、次にwheelie()、最後にstop()を呼び出した結果を、それぞれ個別の行に出力してください。
Motorcycle クラスが、Vehicle から $brand プロパティ、コンストラクタ、そして start() と stop() メソッドの両方を自動的に継承していることに注目してください。子クラスは、自分自身をユニークにするもの(この場合はウィリーをする機能)を定義するだけで済みます。これが継承の力です。共通の機能を親クラスに一度記述すれば、子クラスは独自の特化機能を追加しながら、その機能を再利用できるのです。
チートシート
継承(Inheritance)を使用すると、extendsキーワードを使用して、あるクラスが別のクラスからプロパティやメソッドを取得できるようになります。継承元のクラスは親クラス(または基底クラス)と呼ばれ、継承するクラスは子クラスと呼ばれます。
<?php
class Animal {
public $name;
public function __construct($name) {
$this->name = $name;
}
public function speak() {
return "$this->name makes a sound";
}
}
class Dog extends Animal {
public function fetch() {
return "$this->name fetches the ball";
}
}
$dog = new Dog("Buddy");
echo $dog->speak(); // Buddy makes a sound
echo $dog->fetch(); // Buddy fetches the ball
子クラスは、プロパティ、コンストラクタ、メソッドを含む、親クラスのすべてのpublicおよびprotectedメンバを継承します。また、子クラスは独自の特化したメソッドやプロパティを追加することもできます。
継承はコードの再利用を促進し、クラス間の論理的な関係を確立することで、重複を減らし、コードのメンテナンスを容易にします。
自分で試してみよう
<?php
// Motorcycleクラスをインクルード(Vehicleクラスは既に含まれています)
require_once 'Motorcycle.php';
// 入力を読み込む
$brand = trim(fgets(STDIN));
// TODO: ブランドを指定してMotorcycleオブジェクトを作成する
// TODO: start()の結果を出力する
// TODO: wheelie()の結果を出力する
// TODO: stop()の結果を出力する
?>このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。