LoginSignup
18

More than 5 years have passed since last update.

interfaceがエラーになるケース

Posted at

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

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

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18