Edit report at https://bugs.php.net/bug.php?id=40880&edit=1
ID: 40880
Comment by: postmaster at greg0ire dot fr
Reported by: prometheus__0 at hotmail dot com
Summary: public->protected inheritance causes fatal
Status: Not a bug
Type: Bug
Package: Class/Object related
Operating System: SUSE SLES 10
PHP Version: 5CVS-2007-03-21 (snap)
Block user comment: N
Private report: N
New Comment:
@pajoye : let me explain better what I tried to point out there:
Rasmus says the Fatal error we're getting is here to enforce the LSP.
What I'm saying here is that I'm not getting a signature-compatibility strict notice with
the __construct() example , so obviously, the developer who wrote this notice thinks that LSP should
not apply to __construct() (and I agree with him).
This is just one more argument to convince Rasmus that the LSP does not apply here : obviously, even
some member of the php team are aware of that.
So to sum up the rules you are talking about, though "explained in the PHP manual", should
not apply to __construct() (please read the references I gave in my previous comment to understand
why).
Previous Comments:
------------------------------------------------------------------------
[2012-05-07 09:49:52] pajoye@php.net
@postmaster at greg0ire dot fr
__construct applies only to the class where it is declared.
On the other hand, a method, already defined in the parent class, must be as
visible as the one declared in the parent class and with a compatible signature.
The 2nd clause is not respected in your example as the 1st argument is not
optional. It would work if it was optional, making $a->test() possible ass it is
with the parent class.
All these details are very explained in the PHP manual and other various OOP
references out there.
------------------------------------------------------------------------
[2012-05-07 08:14:16] postmaster at greg0ire dot fr
@rasmus:
Then why is there a strict warning regarding the compatibility of method signatures for this code:
--------------
class Foo {
public function test() {
}
}
class Bar extends Foo {
public function test(ArrayObject $arrayObj, $number = 0) {
/* do stuff with $arrayObj and $number */
}
}
---------------
and not for this one:
---------------
class Foo {
public function __construct() {
}
}
class Bar extends Foo {
public function __construct(ArrayObject $arrayObj, $number = 0) {
/* do stuff with $arrayObj and $number */
}
}
------------
No, as stated here :
- http://stackoverflow.com/questions/5490824/should-constructors-comply-with-the-liskov-substitution-principle
- and here: http://ralphschindler.com/2012/03/09/php-constructor-best-practices-and-the-prototype-pattern,
the LSP does not apply to constructors for several reasons:
- When you call the constructor, you know whether you're using the type or one of its subtypes.
- You can't apply the LSP to an object that does not exist yet.
I think this is a design flaw. Not "massive", but a design flaw indeed.
------------------------------------------------------------------------
[2012-05-06 16:12:00] rasmus@php.net
Most (all?) object oriented languages work this way. Java and C# both do. You can
loosen visibility when you override a parent method, but you can never tighten
it. This is part of what is known as the Liskov Substitution Principle and it is
one of the fundamental principles of object oriented programming. You can read
about at http://en.wikipedia.org/wiki/Liskov_substitution_principle
I can guarantee that abiding by LSP is not a bug
------------------------------------------------------------------------
[2012-05-06 15:40:26] ekincigokan at gmail dot com
Same "problem".
class A{
public function __construct(){}
}
class B extends A {
protected function __construct(){}
}
Please, can you tell us a reason why we can't put an private/protected access to B's
constructor if A's constructor is public ?
Is there any logical reason to this ?
Thanks.
------------------------------------------------------------------------
[2011-09-10 22:27:24] herman dot wetherington at gmail dot com
Apparently, we don't call this a "bug" because this is not caused by a programming
error. So I'm calling it a "massive design flaw" instead.
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
https://bugs.php.net/bug.php?id=40880--
Edit this bug report at https://bugs.php.net/bug.php?id=40880&edit=1