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

From: Date: Thu, 23 Nov 2023 20:31:09 +0000
Subject: [RFC][Discussion] Why can constructors violate LSP?
Groups: php.internals 
Request: Send a blank email to internals+get-121789@lists.php.net to get a copy of this message
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

« previous php.internals (#121789) next »