2021/12/19
前回、PHPの抽象化で アブストラクト(abstract) を取り上げました。
今回は インターフェース(interface) についてエントリーします。
抽象クラスとの違い
抽象クラス(アブストラクト)とインターフェースは外見では挙動が非常に似ています。
共に親クラスで定義して子クラスで機能を実装させています。
違いは
・抽象メソッド+普通のメソッドやフィールドも定義できる
・抽象メソッドのみ定義できる
・アクセス修飾子はpublicのみ
・多重継承(実装)ができる
機能面だけを見ると「アブストラクト」のほうが使いやすく「インターフェース」の出番が見つかりません。
どのように使い分ければいいでしょうか?
アブストラクト
具体的なオブジェクトを作らず(抽象的)、実際の実装は子クラスに任せるケースがあります。
例えば以下のようなケースです。
「動物」クラスを作って「鳴く」メソッドを実装
「猫」なのか?「犬」なのか?わからない。⇒ 実装できない⇒ アブストラクト(抽象クラス)の考え方が生まれる。
1)「動物」クラスを抽象クラスにする
2)「動物」クラスに「鳴く」メソッドを抽象メソッドとして定義
3)「動物」クラスを拡張して「猫」クラスと「犬」クラスを作成
4)「鳴く」メソッドをオーバライド。「猫」クラス→「ニャー」「犬」クラス→「ワン」
インターフェイス
インターフェイスで定義されているメソッドは派生クラスで全て実装しなければなりません。
このことから実装を強制することで、実装漏れを防ぎ、実行時にエラーが出ないようにできます。
インターフェース「飛行生物」を作成して「コウモリ」クラスを実装
「コウモリ」クラスには必ず「飛ぶ」が実装されている→実装漏れを防ぐことができる。
書式
インターフェースの記述方法
「class」の代わりに「interface」というキーワードを使用して定義します。
interface インタフェース名 { }
・定義できるのは抽象メソッドのみ(※「abstract」というキーワードはいらない)
・アクセス修飾子は「public」のみ。
抽象クラスと同様に直接インスタンスの生成はできません。
かならず継承して使うことになるのですが、インターフェースの場合は継承とは言わず、「実装」と呼びます。
インターフェースの実装方法(継承)
実装には「extends」ではなく「implements」というキーワードを使用します。
class クラス名 implements インタフェース名 { }
・インターフェイスで定義されているメソッドは全て実装します。
・アクセス修飾子は「public」のみ。
・引数の名前も完全に一致させる。
チュートリアル
サンプルコードを書きながら理解を深めていきます。
インタフェース「DemoInterface」を実装したクラス「DemoClass」を作成します。
クラス「DemoClass」をインスタンス化にしてメソッドをコール
手順
1)インターフェースを定義
2)実装
3)実行
4)動作確認
1)インターフェースを定義
<?php interface DemoInterface{ public function func1(); public function func2(); } :
2)実装
: class DemoClass implements DemoInterface { public function func1(){ echo "calling func1 with interface is success !<br>"; } public function func2(){ echo "calling func2 with interface is success ! "; } }
3)実行
: $obj = new DemoClass(); $obj->func1(); $obj->func2();
4)動作確認
http://{ホスト名}/demo/interface_demo.php にアクセス
結果は以下のようになります。
以上です。
仕事で Laravel を使っています。気づいたことや新しい発見など情報を発信していきます。問い合わせはこちら。