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:

I filed a separate bug report here: https://bugs.php.net/bug.php?id=61970 so 
that this bug report does not get too cluttered.

I agree that Singleton is not the best of the design patterns, but what if 
someone wants to use it anyway? And what if someone needs a protected / private 
constructor for some reason I cannot imagine?


Previous Comments:
------------------------------------------------------------------------
[2012-05-07 13:26:35] ras...@php.net

This bug report isn't about constructors specifically though. See the bug title 
and the opening points (1) and (2). The fact that __construct was used as an 
example seemed entirely coincidental here.

For constructors specifically, I agree that Liskov can be mostly ignored, and 
we 
do so as you have discovered. The one case where we haven't is visibility. It 
seems a bit of an edge-case to tighten visibility on an inherited constructor 
and if that discourages the singleton pattern we might be doing the world a 
favour here.

------------------------------------------------------------------------
[2012-05-07 12:17:27] postmaster at greg0ire dot fr

@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).

------------------------------------------------------------------------
[2012-05-07 09:49:52] paj...@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] ras...@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

------------------------------------------------------------------------


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

Reply via email to