2016-05-12 11 views
0

PHPのマニュアルは言う:拡張実装は<a href="http://php.net/manual/en/language.oop5.interfaces.php" rel="nofollow">Object Interfaces</a>に

インタフェースで定義されているようにインターフェースを実装するクラスは、全く同じメソッドシグネチャを使用しなければなりません。そうしないと、致命的なエラーが発生します。

ありませんが、以下の場合を考える:私は持っているだけで、引数としてSpecialClassを取る方法foo、および具体的なクラス

class Bar 
{ 
    public function foo(BaseClass $object) 
    { 
     // do something with $object 
    } 
} 

が含まれているインタフェース

interface Foo 
{ 
    public function foo(SpecialClass $object); 
} 

を持っていますfooBaseClassSpecialClass implements BaseClass)の場合を除き、Fooという同じ署名があります。

理論的には、Fooインターフェイスを使用するコードが必要な場合はいつでも、Barのインスタンスを使用できます。すべてが動作するはずです(SpecialClassはBaseClassです)。換言すれば、Barは、というメソッドを持っており、SpecialClassオブジェクトを処理できるため、Fooで宣言されたコントラクトを満たしています。

私のコードでこれを明示的に使用するには、Bar implements Fooと書くことができますが、ドキュメントに記載されているように致命的なエラーが発生します。

この致命的なエラーの原因は何ですか?このようなことが現時点で行われているのか、それともこのようなことを行う特別な理由があるのでしょうか?

答えて

1

DateTimeはStdClassではありませんが、実際には2つの異なるクラスです。

これは@dynamic DataTimeで述べたように、誰もがオブジェクト

+0

それを指摘してくれてありがとう。私は2つのジェネリッククラスを使って質問を訂正しました – marcosh

0

から延びJavaは、stdClassではないではありません。次の例を見てください。

class A { 
    public function foo(); 
} 

class B extends A { 
    public function foo(); 
    public function bar(); 
} 

interface C { 
    public function baz(B $obj) 
} 

class D implements C { 
    public function baz(A $obj); 
} 

Cインタフェースの機能bazは、引数Bを取ることをあなたが見ることができます。実装には引数Aが必要です。問題は、Bにさらに拡張されたインターフェイスがあり、Aがそれを満たさないということです。言い換えれば、Cインターフェイスにアクセスする必要があります。foo()bar()です。しかし、Aにはfoo()しかありません。しかしそれが正反対であれば、それはうまくいくでしょう - BAのインターフェイスを満たしています。

これは一時的な動作ではなく、正しい動作です。

+0

upvoteに感謝しますが、実際に@dynamicは正しいです。 'DateTime'は' stdClass'ではないことを確認できます: 'var_dump(new \ DateTime instanceof \ stdClass);'は 'false'になります –

+0

2つのジェネリッククラスが1つずつ拡張された例を修正しました。さらに、私はあなたの答えに従っているかどうかはわかりません:私は何をしたいのかを示す例を提供して改善してもらえますか? – marcosh

+0

今は大丈夫ですか? :) –

関連する問題

 関連する問題