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