概要
- 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
で確認できる。