On Thu, Nov 23, 2023 at 12:31 PM Robert Landers <landers.rob...@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 -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php