function overriding and class inheritance

php.internals

Emil Ivanov

19 years ago
Hi, I'll try get straight to the point: class C1 {} class C2 extends C1 {} abstract class Work1 { public function f1(C1 $c); } class Work2 extends Work1 { public function f1(C2 $c); } Here I get an an error regarding the prototype missmatch. Wouldn't it be nice to be able to tighted the requirement - C2 is still C1? Regards, Emil Ivanov

Stanislav Malyshev

19 years ago
> I'll try get straight to the point: > class C1 {} > class C2 extends C1 {} > > abstract class Work1 { > public function f1(C1 $c); > } > > class Work2 extends Work1 { > public function f1(C2 $c); > }
This code violates the LSP (*) - if you have object $X of type C1, you can call $work1->f1($X) but not $work2->f1($X) - so $work2 can't be substituted for $work1. Meaning if you had this code: function foo(Work1 $object) { $X = new C1(); $object->f1($X); } it would break with passing Work2 object into it, which violates the principles of inheritance. (*) http://en.wikipedia.org/wiki/Liskov_substitution_principle
-- Stanislav Malyshev, Zend Products Engineer stas@zend.com http://www.zend.com/

Marcus Börger

19 years ago
Hello Emil, learn inheritance rules! And besides PHP follows strict is_a rules. Even if PHP weren't following strict is_a rules: Every Work2 is a Work1 so and so any place that uses with Work1 objects can take Work2 objects. Now "$o->f1($c);" might be using a $o being a work1 or a work2. That means either f1(C1) or f1(C2). The more general one is C1. So Work2::f1(C2) must be wrong becasue it no longer accepts C1. But following is_a rules (even non strict) it needs to. So the code must be wrong. If you need a book to understand the rules I could direct you but I don't recomment reading it really.... best regards marcus Wednesday, May 30, 2007, 12:17:20 AM, you wrote:
> Hi,
> I'll try get straight to the point: > class C1 {} > class C2 extends C1 {}
> abstract class Work1 { > public function f1(C1 $c); > }
> class Work2 extends Work1 { > public function f1(C2 $c); > }
> Here I get an an error regarding the prototype missmatch.
> Wouldn't it be nice to be able to tighted the requirement - C2 is still C1?
> Regards, > Emil Ivanov
Best regards, Marcus

Paweł Stradomski

19 years ago
Emil Ivanov wrote:
> class C1 {} > class C2 extends C1 {} > > abstract class Work1 { >  public function f1(C1 $c); > } > > class Work2 extends Work1 { >  public function f1(C2 $c); > }
Strange thing is I don't get any error message here, although there definitely should be one. PHP 5.2.2-pl1-gentoo (cli) (built: May 21 2007 12:36:57) Copyright (c) 1997-2007 The PHP Group Zend Engine v2.2.0, Copyright (c) 1998-2007 Zend Technologies And regarding your code - it should work the other way round - you can only loose preconditions and tighten postconditions, which is a result of substituion rule already mentioned by Stanislav.
-- Paweł Stradomski