On Fri, Jun 19, 2020 at 10:17 AM Nikita Popov <nikita....@gmail.com> wrote:
> On Tue, Jun 16, 2020 at 11:19 AM Marco Pivetta <ocram...@gmail.com> wrote: > >> Maybe the magic methods would indeed all need to respect `final`, and we >> haven't considered all scenarios? >> > > Or ... we could just not change this part of the behavior at all :) If we > acknowledge that this is definitely useful for constructors and possibly > useful for cloning, then maybe it is useful for other things as well? I > still haven't heard a reason *why* we would want to do this change (not the > general change, but specifically the "private final" one). > > This stuff really isn't super important to me, and I'd be happy to > sacrifice this functionality in the name of the greater good, but I > honestly don't understand what that greater good is in this case. It seems > like a strict loss in functionality. > > Regards, > Nikita > Hi Nikita, The motivations for changing the behavior of final private are the following: - Theoretical: Even though private members are technically inherited by child classes, they are not overridable. You can already have public methods in a child class with the same name as a private parent, but you are not overriding it (if you call that method in the parent, you will use the private method declared there. If you call it in the child, you will use the public method declared there - https://3v4l.org/TImO8). You can have different visibility, different signatures (thanks to a bugfix that was actually my first contribution to PHP :) ) and the methods are completely unrelated except that they share the name. Sharing the name shouldn't be a reason to enforce any inheritance rules. - Implementation: My preferred way to implement this would have been to skip the call to `do_inheritance_check_on_method_ex` on private methods completely, as that would make the intention very clear. The only reason why I couldn't is the check for abstract private methods coming from traits. And currently, the ZEND_ACC_CHANGED flag is also added there, but I think that could be easily avoided. - Other languages: - Java: https://www.ideone.com/P71k8J - final has no effect when added to a private method ( https://www.javaworld.com/article/2077399/private-and-final.html) - C#: https://www.ideone.com/i1OtFe - In C#, for a method to be overridable it has to be marked as virtual. In this snippet, we are not marking it as virtual (hence it acts as final) and nothing prevents us from declaring it in the child class. Regards, Pedro