Re: [RFC][Discussion] Why can constructors violate LSP?

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

« previous php.internals (#121803) next »