1.インターフェースは「interface」キーワードを使って定義する。
2.インターフェースは実装を含むメソッドは定義できない。定数は定義できる。
3.インターフェースは多重実装が可能。
インターフェースとは
インターフェースは実装しなければいけないメソッドを定義するものです。
クラスはインターフェースをimplements演算子で「実装する」と指定することで、
そのインターフェースで定義づけられたメソッドを実装しなければならなくなります。
その点、抽象クラスと似ている部分もありますが、
抽象クラスには具象メソッドも定義することができましたが、
インターフェースはメソッドの実装は全く定義できません。
また、インターフェース内で定義される全てのメソッドはpublicである必要があります。
省略した場合は自動的にpublicになります。
インターフェース(と抽象クラス)が、コードの基本設計にあたり、
具象クラスが、コードの詳細設計にあたります。
ですので、最初からクラスを書くのでなく、
インターフェースを先に書くことで、
細かい実装に拘泥せず、必要なコードの大枠を定義できる利点があります。
インターフェースの定義構文
1 2 3 | interface インターフェース名{ public function メソッド名(); } |
インターフェースを実装するクラスの構文
1 2 3 | class クラス名 implements インターフェース名{ } |
インターフェースの継承
1 2 3 | interface 子インターフェース名 extends 親インターフェース名{ } |
インターフェースと定数
インターフェースでは定数を定義することができます。
しかし、その定数を、実装先のクラスでオーバーライドできません。
1 2 3 4 5 6 7 8 9 10 11 | <?php interface Constants{ const x = 100; } class Constants_ implements Constants{ const x = 1; } echo ( new Constants_())->x; ?> |
インターフェースのサンプル
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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に定義した全てのインターフェースで
宣言されているメソッドを実装する必要があります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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つのインターフェースを多重実装させれば、同じ目的が達成できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | <?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>" ; ?> |
インターフェースと抽象クラスの併用
以下のように、抽象クラスを継承し、インターフェースを実装したクラスを定義することも可能です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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(); |