Re: [RFC][Discussion] Why can constructors violate LSP?
| From: | Mark Trapp | Date: | Fri, 24 Nov 2023 11:36:32 +0000 |
| Subject: | Re: [RFC][Discussion] Why can constructors violate LSP? | ||
| References: | 1 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-121803@lists.php.net to get a copy of this message | ||
On Thu, Nov 23, 2023 at 12:31 PM Robert Landers
<landers.robert@gmail.com> wrote:
>
> Hello Internals,
>
> As you may know, an inherited method cannot reduce the visibility of
> an overridden method. For example, this results in a fatal error
> during compilation:
>
> class P {
> public function hello($name = 'world') {
> echo "hello $name\n";
> }
> }
>
> class C extends P {
> private function hello($name = 'world') {
> parent::hello($name);
> echo "goodbye $name\n";
> }
> }
>
> However, we can make certain methods private anyway, namely,
> constructors (I haven't gone hunting for other built-in methods yet).
> This is perfectly allowed:
>
> class P {
> public function __construct($name = 'waldo') {
> echo "hello $name\n";
> }
> }
>
> class C extends P {
> private function __construct($name = 'world') {
> parent::__construct($name);
> echo "goodbye $name\n";
> }
> }
>
> To my somewhat trained eye, this appears to violate the Liskov
> Substitution Principle, for example, this now can have hidden errors:
>
> function create(P $class) {
> return new (get_class($class))();
> }
>
> proven by:
>
> $c = (new ReflectionClass(C::class))
> ->newInstanceWithoutConstructor();
>
> create($c);
>
> Even though we thought we knew that the constructor was declared public.
>
> I'd like to propose an RFC to enforce the covariance of constructors
> (just like is done for other methods), to take effect in PHP 9, with a
> deprecation notice in 8.3.x.
>
> I'm more than happy to implement it.
>
> Does anyone feel strongly about this one way or the other?
>
> Robert Landers
> Software Engineer
> Utrecht NL
Hi Robert,
Liskov and Wing explicitly exempted constructors in their original
paper describing the principle:
http://reports-archive.adm.cs.cmu.edu/anon/1999/CMU-CS-99-156.pdf
> 4.1 Type Specifications
>
> A type specification includes the following information:
>
> - The type's name
> - A description of the type's value space
> - A definition of the type's invariant and history properties
> - For each of the type's methods:
> - Its name;
> - Its signature including signaled exceptions;
> - Its behavior in terms of pre-conditions and post-conditions.
>
> Note that the creators are missing. Omitting creators allows subtypes to provide different
> creators than their supertypes. In addition, omitting creators makes it easy for a type to have
> multiple implementations, allows new creators to be added later, and re ects common usage: for
> example, Java interfaces and virtual types provide no way for users to create objects of the type.
(Creators is Liskov's word for constructors, which they later define
in the paper.)
Hope that helps.
- Mark Trapp