Re: Implementing interface method with child class in parameter def (Bug #42330)
| From: | Leigh | Date: | Wed, 17 Sep 2014 14:56:32 +0000 |
| Subject: | Re: Implementing interface method with child class in parameter def (Bug #42330) | ||
| References: | 1 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-77292@lists.php.net to get a copy of this message | ||
On 17 September 2014 15:52, Christian Stoller <stoller@leonex.de> wrote:
> Hello all,
>
> I hope the subject is not misleading. Please look at the following code:
>
> <?php
> class A { }
>
> class B extends A { }
>
> interface C {
> function foo(A $a);
> }
>
> class D implements C {
> public function foo(B $b) {
>
> }
> }
>
> This code produces a "Fatal error: Declaration of D::foo() must be
> compatible with C::foo(A $a) in /xyz/inheritance.php on line 10"
> (see http://3v4l.org/l2M0f).
>
> I don't get the reason for that behavior (and I could not find any
> documentation about that, at least not at
> http://php.net/manual/en/language.oop5.typehinting.php).
>
> I have already found https://bugs.php.net/bug.php?id=42330 but
> Derick's
> response does not help me and the linked file cannot be accessed
> anymore.
>
> I'd say that it is absolutely legal to define a more specialized
> type in a child or implementing class, or would this have any bad
> side effects?
>
> Thanks and best regards
> Christian
Interesting that you bring this up today, I was literally talking to
NikiC about this yesterday.
This is what is called a covariant method argument type, and the
reason that it is invalid is because if you pass an instance of D, to
function that allows anything implementing C, then it would be
acceptable to call foo() with an instance of A.
The relevant article on wikipedia:
https://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)#Covariant_method_argument_type