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".
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
Hi.
The point is: traits are not inheritance. It's assisted copy-and-paste.
When you use a trait, it's like you typed those methods yourself.
But if you type them in the class that's using the trait,
you throw away the method definition from the trait and use the one from
the class.
You can see here what the final keyword on your trait is intended for:
I hope I was able to help.
Best regards,
Erick
Em qua., 14 de jun. de 2023 às 16:34, Juliette Reinders Folmer <
php-internals_nospam@adviesenzo.nl> escreveu:
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 thefinal
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".
Which brings me to my second point: in PHP 8.0 the use of the
final
keyword withprivate
methods has been turned into awarning
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 expectfinal private
methods in traits to be
exempt from that warning, but turns out that that will still throw the
warning: https://3v4l.org/Vb0S2Is there anyone who can shed some light on this behaviour ?
Smile,
Juliette