Re: AW: [PHP-DEV] Allow dropping typehints during inheritance
| From: | Rowan Collins | Date: | Thu, 05 Feb 2015 12:32:59 +0000 |
| Subject: | Re: AW: [PHP-DEV] Allow dropping typehints during inheritance | ||
| References: | 1 2 3 4 5 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-81916@lists.php.net to get a copy of this message | ||
Robert Stoll wrote on 05/02/2015 12:16:
Indeed. The contract states that if you know you have an instance of C, you can pass any instance of A to its foo method. If you are given an instance of D, that contract will be violated, because instances of A which are not instances of B will be rejected. The other way around, however, is theoretically fine (though not implemented in PHP because its complicated to check): class X { public function bar(B $thing) {} } class Y extends X { public function bar(A $thing) {} } Here, the contract states that if you have an instance of X, you can pass any instance of B to its bar method. If you are given an instance of Y, you can still pass any B to its bar method, so the contract is met. If you /know/ that you have an instance of Y, you know you can also pass other types of A//. A real-life example that came to mind previously was an event handler interface that told implementers exactly what kind of event to expect, being implemented by a logger that can actually accept any kind of event you give it. As long as the event dispatchers knows that the logger accepts the event its dispatching, it doesn't care what else it can do. Regards, -- Rowan Collins [IMSoP]-----Ursprüngliche Nachricht----- Von: julienpauli@gmail.com [mailto:julienpauli@gmail.com] Im Auftrag von Julien Pauli Gesendet: Donnerstag, 5. Februar 2015 13:10 An: Andrea Faulds Cc: Hannes Magnusson; Nikita Popov; PHP internals Betreff: Re: [PHP-DEV] Allow dropping typehints during inheritance On Thu, Feb 5, 2015 at 2:08 AM, Andrea Faulds <ajf@ajf.me> wrote:Because this would be covariance and violates LSP. Considering the following: function foo(C $c){Hi Hannes,If we allow larger type, why doesn't such code work ? interface A { } interface B extends A { } class C {On 4 Feb 2015, at 23:58, Hannes Magnusson <hannes.magnusson@gmail.com>wrote:So what it supports "more inputs"? It does constitute an LSP violation. "more inputs" is not what the guarantee is at all, if that is what you want you'd typehint on a interface. It is a LSP failure to allow a string, or any other scalar value, when the parent requires a specific type/object. It sucks that we fail our arginfo very frequently, but this is the wayit is :] An interface requires only a minimum standard for accepted input. If a class implementing that interface allows a wider range of values, but still allows at least what the interface requires it to, it is not an LSP violation. Scalars are not special.public function foo(A $a) { }} class D extends C {public function foo(B $a) { } // E_STRICT }This is wrong IMO.$c->foo(new A);} if you substitute C with D then suddenly the code would not work anymore.