概要
- PHPではクラスの多重継承はできないが、複数のインターフェイスをインプリメントできる
- インターフェイスでは実装すべき関数の宣言のみ行い、実装はこれをインプリメントした関数で行う
- これにより、インターフェイスを実装するクラスが持つべきメソッドが明示・保証される
基本形
インターフェイスの宣言・定義
|
1 2 3 4 5 |
interface インターフェイス名 { public function メソッド名1; public function メソッド名2; ..... } |
インターフェイスの実装
|
1 2 3 4 5 6 7 8 9 10 11 |
class クラス名 implements インターフェイス名 { ..... public function メソッド名1(...) { メソッド1の実装 } public function メソッド名2(...) { メソッド2の実装 } ..... } |
実装例
RPGのキャラクターをイメージしたキャラクターを実装していく。
親クラス
全てのキャラクターはCharacterClassクラスを継承し、
- 名前を持つ
- 武器で攻撃する
attack()メソッドを持つ
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
class CharacterClass { private $name; public function __construct($name) { $this->name = $name; } public function getName() { return $this->name; } public function attack() { echo $this->name . "は武器で攻撃した!\n"; } } |
Swordfighterクラス
SwordfighterクラスとWizardクラスはCharacterClassを継承し、武器による攻撃ができる。
|
1 2 |
class Swordfighter extends CharacterClass { } |
Spellcasterインターフェイス
Spellcasterインターフェイスは呪文を使える種族を表し、呪文を唱えるspell()メソッドを持つ。spell()メソッドの実装は、インプリメントするクラスで定義する必要がある。
|
1 2 3 |
interface Spellcaster { public function spell(); } |
Wizardクラス
WizardクラスはCharacterClassクラスを継承するとともに、Spellcasterインターフェイスをインプリメントする。Wizardは武器による攻撃ができるほか、spell()メソッドで攻撃魔法を実装している。
|
1 2 3 4 5 |
class Wizard extends CharacterClass implements Spellcaster { public function spell() { echo $this->getName() . "は攻撃魔法を唱えた!\n"; } } |
Priestクラス
PriestクラスはCharacterClassクラスを継承するとともに、Spellcasterインターフェイスをインプリメントする。Priestは武器による攻撃ができるほか、spell()メソッドで味方の治療を実装している。
|
1 2 3 4 5 |
class Priest extends CharacterClass implements Spellcaster { public function spell() { echo $this->getName() . "は味方の傷を癒した!\n"; } } |
ポリモーフィズムによる実行
Swordfighter、Wizard、Priestのインスタンスを生成し、$party_members配列に保存する。
- 全てのメンバーに武器で攻撃させる
- その後、
Spellcasterのメンバーに呪文使用させる
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
$party_members = []; $party_members[] = new Swordfighter('アーサー'); $party_members[] = new Wizard('ハリー'); $party_members[] = new Priest('サンゾウ'); echo "武器攻撃ターン\n"; foreach ($party_members as $member) { $member->attack(); } echo "呪文使用ターン\n"; foreach ($party_members as $member) { if ($member instanceof Spellcaster) { $member->spell(); } } // 武器攻撃ターン // アーサーは武器で攻撃した! // ハリーは武器で攻撃した! // サンゾウは武器で攻撃した! // 魔法攻撃ターン // ハリーは攻撃魔法を唱えた! // サンゾウは味方の傷を癒した! |
インターフェイス実装の確認
あるクラスが指定したインターフェイスをインプリメントしているかどうかは、クラスのチェックと同じ型演算子instanceofで確認できる。