# One more Liskov Subs. and parameter checking notice

- Thread: https://externals.io/message/56801
- Original archive: https://news-web.php.net/php.internals/56801
- Started by jpauli on 2011-12-06T13:54:17+00:00
- Messages: 2
- 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

---

## #56801 — jpauli — 2011-12-06T13:54:17+00:00

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

Greetings PHP Intern@ls :)

There is a PHP behavior I disagree with regarding OO model.
It's been here for a long time (5.0 ??, at least 5.2, 5.3 and 5.4) , here
it is :

<?php
interface Iface1 { }
interface Iface2 extends Iface1 { }

class Foo {
    public function bar(Iface1 $arg) { }
}

class Foo2 extends Foo {
    public function bar(Iface2 $arg) { }
}
?>
Strict Standards: Declaration of Foo2::bar() should be compatible with that
of Foo::bar()


I find this wrong.
Liskov (and the error message) says we must stay "compatible" in our
inheritence.
The fact is that we are in the code above :
- A uses IfaceA
- B extends A
- B should be able to overwrite A's method typing their IfaceA params on
IfaceB, if IfaceB extends IfaceA (and is thus compatible with it).

Thoughts ?

Julien.Pauli

---

## #56803 — Etienne Kneuss — 2011-12-06T14:01:25+00:00

URL: https://externals.io/message/56801#56803 · In reply to: #56801

Hi,



> Greetings PHP Intern@ls :)
>
> There is a PHP behavior I disagree with regarding OO model.
> It's been here for a long time (5.0 ??, at least 5.2, 5.3 and 5.4) , here
> it is :
>
> <?php
> interface Iface1 { }
> interface Iface2 extends Iface1 { }
>
> class Foo {
>    public function bar(Iface1 $arg) { }
> }
>
> class Foo2 extends Foo {
>    public function bar(Iface2 $arg) { }
> }
> ?>
> Strict Standards: Declaration of Foo2::bar() should be compatible with that
> of Foo::bar()
>
>
> I find this wrong.
> Liskov (and the error message) says we must stay "compatible" in our
> inheritence.
> The fact is that we are in the code above :
> - A uses IfaceA
> - B extends A
> - B should be able to overwrite A's method typing their IfaceA params on
> IfaceB, if IfaceB extends IfaceA (and is thus compatible with it).


> Thoughts ?
>

No, that makes B incompatible with A.

Consider calling $obj->bar($obj) where obj implements IFaceA and not
IfaceB, if $obj is of class A, this is ok, if $obj is of class B, this is
invalid.

In other terms, arguments' types should be contra-variant. Currently PHP
expects them to be invariant, but there is already an RFC discussing how to
extend it:

https://wiki.php.net/rfc/prototype_checks

Best,


>
> Julien.Pauli
>



-- 
Etienne Kneuss
http://www.colder.ch
