Traits "implements" support

php.internals

David Rodrigues

5 years ago
Hello! Now with PHP 8, traits supports abstract functions that should be implemented by the class that uses this trait. So is it now possible that traits could have support to implements too? So when class uses this trait, it will be an implementation of X interface and will have to implement methods based on it. interface A { public function x(); } trait B implements A { public function y() { $this->x(); } // public function x() still not implemented. } class Z { // impliticy implements A interface due to B trait. use B; public function x() {} // required! } Atenciosamente, David Rodrigues

Pierre

5 years ago
Le 26/11/2020 à 17:50, David Rodrigues a écrit :
> Hello! > > Now with PHP 8, traits supports abstract functions that should be > implemented by the class that uses this trait. > > So is it now possible that traits could have support to implements too? So > when class uses this trait, it will be an implementation of X interface and > will have to implement methods based on it. > > interface A { > public function x(); > } > > trait B implements A { > public function y() { $this->x(); } > // public function x() still not implemented. > } > > class Z { // impliticy implements A interface due to B trait. > use B; > public function x() {} // required! > } > > > Atenciosamente, > David Rodrigues >
Hello, I'd love this too, but I'm not sure what would be the static code validation behavior, knowing that you can rename methods of traits when using them in a class: should the trait method not be validated ? Should the final class be validated after the trait has been used, meaning that if a method name change, the final class must re-implement it ?
-- Pierre

Nikita Popov

5 years ago
On Thu, Nov 26, 2020 at 5:53 PM Pierre R. <pierre-php@processus.org> wrote:
> Le 26/11/2020 à 17:50, David Rodrigues a écrit : > > Hello! > > > > Now with PHP 8, traits supports abstract functions that should be > > implemented by the class that uses this trait. > > > > So is it now possible that traits could have support to implements too? > So > > when class uses this trait, it will be an implementation of X interface > and > > will have to implement methods based on it. > > > > interface A { > > public function x(); > > } > > > > trait B implements A { > > public function y() { $this->x(); } > > // public function x() still not implemented. > > } > > > > class Z { // impliticy implements A interface due to B trait. > > use B; > > public function x() {} // required! > > } > > > > > > Atenciosamente, > > David Rodrigues > > > Hello, > > I'd love this too, but I'm not sure what would be the static code > validation behavior, knowing that you can rename methods of traits when > using them in a class: should the trait method not be validated ? Should > the final class be validated after the trait has been used, meaning that > if a method name change, the final class must re-implement it ? >
Common misconception: It's not possible to rename methods of traits, you can only create aliases. That said, there's still an issue in that you might resolve a conflict in favor of an identically named method that uses a different signature. Note that Hack uses a "require implements" syntax instead, which makes it clear that the interface needs to be implemented by the using class: https://docs.hhvm.com/hack/classes/trait-and-interface-requirements Regards, Nikita

Pierre

5 years ago
Le 30/11/2020 à 16:19, Nikita Popov a écrit :
> Common misconception: It's not possible to rename methods of traits, you > can only create aliases. That said, there's still an issue in that you > might resolve a conflict in favor of an identically named method that uses > a different signature. > > Note that Hack uses a "require implements" syntax instead, which makes it > clear that the interface needs to be implemented by the using class: > https://docs.hhvm.com/hack/classes/trait-and-interface-requirements > > Regards, > Nikita
Sorry for the misconception/confusion. Probably what's missing is something that looks like Java's interface with default methods, or something like that. Very often you use traits to partially implement an interface, and leave room for classes using this "partial implementation" for inheriting from another class. It looks like multiple inheritance without being it. What is really needed when doing this is: * Your class using this trait must implement the interface, * The trait methods must be validated against the interface contract. If I understand it well, when compiling PHP kinda copy-pastes the trait methods onto the class (trait doesn't exist as a type by itself, am I wrong?) then it validates the class, which solves the second point, trait methods are in the end, validated against the interface contract. What's missing here is the automatic interface usage, but more importantly, IDE support for the trait, and the information in the code that the trait does implement partially the interface (people who read the code cannot guess if it's mis-documented). Regards, Pierre