interfaceがエラーになるケース

  • 13
    Like
  • 2
    Comment
More than 1 year has passed since last update.

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(){}
  //...(省略)
}

他にもあったら教えてください。