# function overriding and class inheritance

- Thread: https://externals.io/message/29901
- Original archive: https://news-web.php.net/php.internals/29901
- Started by Emil Ivanov on 2007-05-29T22:17:20+00:00
- Messages: 4
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #29901 — Emil Ivanov — 2007-05-29T22:17:20+00:00

URL: https://externals.io/message/29901#29901

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

---

## #29903 — Stanislav Malyshev — 2007-05-29T22:39:14+00:00

URL: https://externals.io/message/29901#29903 · In reply to: #29901

> 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/

---

## #29905 — Marcus Boerger — 2007-05-29T22:47:47+00:00

URL: https://externals.io/message/29901#29905 · In reply to: #29901

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

---

## #29907 — pstradomski@gmail.com — 2007-05-29T23:06:02+00:00

URL: https://externals.io/message/29901#29907 · In reply to: #29901

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
