Unexpected behaviour when using Traits with final methods
| From: | Juliette Reinders Folmer | Date: | Wed, 14 Jun 2023 19:33:53 +0000 |
| Subject: | Unexpected behaviour when using Traits with final methods | ||
| Groups: | php.internals | ||
| Request: | Send a blank email to internals+get-120576@lists.php.net to get a copy of this message | ||
Hi all,
I'm running into something which peaked my curiousity due to its unexpected behaviour, so I'm writing to the list in the hopes of finding out whether this is by design, a bug or an oversight which should be fixed (via an RFC?).
The precedence order is that members from the current class override Trait methods, which in turn override inherited methods.Source: https://www.php.net/manual/en/language.oop5.traits.php#language.oop5.traits.precedence If one would want to prevent the "current class" from being able to override a trait method, I would expect that the
final keyword would be able to do this, just like it would when a method is inherited from a parent class.
Unfortunately, that does not seem to work and it appears that the current class can freely override final methods from a trait:
trait Foo {
final protected function bar() {
echo 'Foo';
}
}
class FooBar {
use Foo;
public function __construct() {
$this->bar();
}
protected function bar() {
echo 'FooBar';
}
}
new FooBar(); // Prints "FooBar".
https://3v4l.org/hlirb
Which brings me to my second point: in PHP 8.0 the use of the final keyword with private methods has been turned into a warning via this RFC: https://wiki.php.net/rfc/inheritance_private_methods
... but the "current class" has access to private methods inherited from a trait, so I would expect final private methods in traits to be exempt from that warning, but turns out that that will still throw the warning: https://3v4l.org/Vb0S2
Is there anyone who can shed some light on this behaviour ?
Smile,
Juliette