5

このエラーが表示される理由:

Fatal error: Declaration of ConcreteFooMapper::load() must be compatible with that of AbstractFooMapper::load() on line 18

このコードから:

<?php
interface Foo {
    public function foo();
}

class ConcreteFoo implements Foo {
    public function foo() {

    }
}

abstract class AbstractFooMapper {
    abstract public function load(Foo $entity, array $data);
}

class ConcreteFooMapper extends AbstractFooMapper {
    public function load(ConcreteFoo $entity, array $data) {

    }
}
?>

私の最初の考えは、これはバグだということです。PHP は、メソッド宣言を評価しているときに、 ConcreteFooがFooを実装していることを検出していません。このコードを実行すると、次のようになると思います。

<?php
interface Foo {
    public function foo();
}

class ConcreteFoo implements Foo {
    public function foo() {

    }
}

$foo = new ConcreteFoo();

if ($foo instanceof Foo) 
{
    print 'w00t!';
} 
else 
{
    print 'FAIL!';
}
?>

それはw00tを印刷します!ConcreteFooがFooのインスタンスであることを示します。

この動作が正しいかどうかについての洞察はありますか?

4

3 に答える 3

5

docsによると、型ヒントは正確に一致する必要があります。

于 2012-12-14T03:15:58.187 に答える
3

インターフェイスを実装するクラスは、インターフェイスで定義されているものとまったく同じメソッド シグネチャを使用する必要があります。そうしないと、致命的なエラーが発生します。抽象クラスを拡張するクラスについても同じルールです。

詳細はこちらこちらもご覧ください

そして、これは正しい行動 \ ロジックです。

ここをチェック抽象型は、プロトコルの定義と実施に使用できるという点で便利です。プロトコルを実装するすべてのオブジェクトがサポートしなければならない一連の操作。

あなたのコードが例外なく動作すると仮定すると、次の問題があります: ConcreteFooMappersome のインスタンスをメソッドのclass ConcreteFoo2 implements Fooパラメーターとして使用することはできませんが、(Abstract クラスの定義により) 使用する必要があります。load

また、同じ署名を使用しても、実際には問題ありません。すべてのクラス\タイプ情報が利用可能になります。次のコードを確認してください

<?php
interface Foo {
        public function foo();
}

class ConcreteFoo implements Foo {
        public function foo() {
        }
}

abstract class AbstractFooMapper {
        abstract public function load(Foo $entity, array $data);
}

class ConcreteFooMapper extends AbstractFooMapper {
        public function load(Foo $entity, array $data) {
                var_dump($entity instanceof Foo);
                var_dump($entity instanceof ConcreteFoo);
        }

}

$someConcreteFoo = new ConcreteFoo();
$someFooMapper = new ConcreteFooMapper();

$someFooMapper->load($someConcreteFoo, array('somekey' => 'somevalue'));
// output
// bool(true) bool(true)  

?>
于 2012-12-14T03:50:08.130 に答える