【PHP応用】インターフェース
1.インターフェースは「interface」キーワードを使って定義する。
2.インターフェースは実装を含むメソッドは定義できない。定数は定義できる。
3.インターフェースは多重実装が可能。
インターフェースとは
インターフェースは実装しなければいけないメソッドを定義するものです。
クラスはインターフェースをimplements演算子で「実装する」と指定することで、
そのインターフェースで定義づけられたメソッドを実装しなければならなくなります。
その点、抽象クラスと似ている部分もありますが、
抽象クラスには具象メソッドも定義することができましたが、
インターフェースはメソッドの実装は全く定義できません。
また、インターフェース内で定義される全てのメソッドはpublicである必要があります。
省略した場合は自動的にpublicになります。
インターフェース(と抽象クラス)が、コードの基本設計にあたり、
具象クラスが、コードの詳細設計にあたります。
ですので、最初からクラスを書くのでなく、
インターフェースを先に書くことで、
細かい実装に拘泥せず、必要なコードの大枠を定義できる利点があります。
インターフェースの定義構文
interface インターフェース名{ public function メソッド名(); }
インターフェースを実装するクラスの構文
class クラス名 implements インターフェース名{ }
インターフェースの継承
interface 子インターフェース名 extends 親インターフェース名{ }
インターフェースと定数
インターフェースでは定数を定義することができます。
しかし、その定数を、実装先のクラスでオーバーライドできません。
<?php interface Constants{ const x = 100; } class Constants_ implements Constants{ const x = 1; } echo (new Constants_())->x; ?>
インターフェースのサンプル
interface If2_3_1{ const X = "xxx"; function if_x(); } class Sample2_3_1 implements If2_3_1{ //const X = "xxx2"; function if_x(){ echo self::X; } } $s = new Sample2_3_1; $s->if_x();
インターフェースの多重実装
インターフェースは多重実装が可能です。
その場合、implementsに定義した全てのインターフェースで
宣言されているメソッドを実装する必要があります。
interface If2_3_2_1{ function a(); } interface If2_3_2_2{ function b(); } class Sample2_3_2 implements If2_3_2_1, If2_3_2_2{ function a(){ echo "a"; } function b(){ echo "b"; } }
補足
PHPでは多重継承(複数のクラスの継承)はできません。
その代替として、多重実装を使います。
たとえば、CSVにできるクラスと、JSONにできるクラスというクラス定義をして、
そのあとに、CSVにもJSONにもできるクラスを用意しようとしても、
できません。
代わりに、CSVにできるインターフェースと、JSONにできるインターフェースを用意し、
目的のクラスに、2つのインターフェースを多重実装させれば、同じ目的が達成できます。
<?php interface CSVable { function toCSV(); } interface JSONable { function toJSON(); } class Product implements CSVable, JSONable { public function __construct(int $id, String $name) { $this->id = $id; $this->name = $name; } public function toCSV() { $value = $this->id.",".$this->name; return $value; } public function toJSON() { $candidate = json_encode($this); if($candidate === false) { return "{}"; } return $candidate; } } $product = new Product(1, "PC"); echo "CSV : ".$product->toCSV()."</br>"; echo "JSON : ".$product->toJSON()."</br>"; ?>
インターフェースと抽象クラスの併用
以下のように、抽象クラスを継承し、インターフェースを実装したクラスを定義することも可能です。
interface IF2_3_3{ function a(); function c(); } abstract class Abs2_3_3{ abstract function a(); function b(){ echo "b"; } } class Sample2_3_3 extends Abs2_3_3 implements IF2_3_3{ function a(){ echo "a"; } function c(){ echo "c"; } } $s = new Sample2_3_3(); $s->a(); $s->b(); $s->c();