PHPのinterfaceは多重継承が可能(一つのクラスにつき複数のインターフェースを実装したと宣言可能)であるが、実際にはFatal Errorになって実装できないケースがあるのでまとめる。
シグネチャが違う2つのinterface
interfaceはシグネチャまで揃っていることを保証するためのものなので、違うシグネチャを同時に実装することはできない。
<?php
interface i1 {
function hoge();
}
interface i2 {
function hoge(array $a); //引数定義が違う
}
class A implements i1, i2
{
function hoge() {} //i2に合ってないというFatal Error
//function hoge(array $a) {} //こう書くとi1に合ってないというFatal Error
}
シグネチャが同一であれば問題なく実装できる。
同じinterfaceを複数回implementsに並べる
多重に実装できるはずだが、これはエラーになる。
<?php
class A implements i1, i1
{
function hoge(){};
}
継承したinterfaceを継承順と逆に並べる
すごくわかりにくい。
<?php
interface i1 {
function foo();
}
interface i2 extends i1 {
function moo();
}
class A implements i2, i1 //Fatal Error
{
function foo(){}
function moo(){}
}
なお、implementsにi1, i2の順で書けば、エラーは起きない(!)
この場合、単にimplements i2としておけばi1も実装したことになる((new A) instanceof i1)ので、書き方が変ではある。
エラーの理由がわかりにくいのでやっかいである。親interface→派生interfaceの順ならエラーにならないと覚える。
interfaceは多重に実装可能なので、あまり継承を使う場面はないような気もする。(タイプヒントに使いたいときだけだろう)
重箱の隅っぽいな。
IteratorとIteratorAggregate
特殊な例だけれど、組み込みのIteratorとIteratorAggregateは同時に実装しようとするとFatal Errorになる。どちらか片方のみを使うことで解決する。
<?php
// エラーになる
class A implements Iterator, IteratorAggregate
{
function getIterator(){}
//...(省略)
}
他にもあったら教えてください。