Remove inappropriate inheritance signature checks on private methods View as Markdown

Implemented (PHP 8.0)
Authors
Pedro Magalhães, pmmaga@php.net
Date
2020-04-16
Version
0.3
Target
8.0
Source
wiki.php.net/rfc/inheritance_private_methods

Vote

Remove inappropriate inheritance signature checks on private methods closed
Yes
24
No
11
35 voters
alcaeus Yes 2020-06-16 08:21
alec Yes 2020-06-16 09:12
asgrim Yes 2020-06-18 12:42
ashnazg No 2020-06-17 15:34
bwoebi No 2020-06-19 09:25
colinodell Yes 2020-06-15 23:01
cpriest Yes 2020-06-20 20:57
danack No 2020-06-24 14:59
derick Yes 2020-06-26 09:31
duncan3dc Yes 2020-06-29 15:12
galvao Yes 2020-06-15 22:09
geekcom Yes 2020-06-16 00:58
girgias Yes 2020-06-15 20:57
jbnahan Yes 2020-06-22 11:52
kalle Yes 2020-06-15 20:50
kguest Yes 2020-06-17 14:05
klaussilveira No 2020-06-16 18:23
kocsismate Yes 2020-06-19 17:07
lcobucci Yes 2020-06-27 06:37
narf No 2020-06-19 11:21
nicolasgrekas Yes 2020-06-16 08:06
ocramius Yes 2020-06-15 21:45
patrickallaert No 2020-06-16 10:14
pmmaga Yes 2020-06-15 20:36
reywob No 2020-06-16 07:37
salathe No 2020-06-26 10:17
sergey No 2020-06-16 12:30
sirsnyder Yes 2020-06-15 22:53
stas Yes 2020-06-28 19:08
svpernova09 Yes 2020-06-18 14:23
tandre No 2020-06-19 13:51
theodorejb Yes 2020-06-26 12:08
weierophinney Yes 2020-06-25 19:21
yunosh Yes 2020-06-25 19:08
zimt No 2020-06-17 07:07

Discussions on the mailing list

Remove LSP checks on static methods?
by Mike Schinkel · 6 messages
Unexpected behaviour when using Traits with final methods
by Juliette Reinders Folmer · 2 messages

RFC text

Copied from wiki.php.net, last synchronized Oct 13, 2026 11:51 UTC

Introduction

Currently, a method with the same name as a parent's method, is still checked for some inheritance rules regardless of the parent's method visibility.

This leads to inheritance checks being executed even if the parent's method is private. Since private methods are not callable outside of the scope they are defined in, these rules should not be applied.

Some rules are already skipped like the number of arguments or their type, but other rules are still enforced. Namely:

  • When a method has the same name as a parent's final private method
  • When a method has the same name as a parent's static private method and the child's method is non-static, or vice-versa
  • When a method has the same name as a parent's concrete private method and the child's method is abstract

The documentation explicitly states that only public and protected methods are inherited:

For example, when you extend a class, the subclass inherits all of the public and protected methods from the parent class. Unless a class overrides those methods, they will retain their original functionality.

Proposal

This RFC proposes removing these inappropriate inheritance checks that are still enforced in the case of the parent method being private.

In the current state:

<?php
 
class A 
{ 
    final private function finalPrivate() { 
        echo __METHOD__ . PHP_EOL; 
    } 
} 
 
class B extends A 
{ 
    private function finalPrivate() { 
        echo __METHOD__ . PHP_EOL; 
    } 
}

Produces:

Fatal error: Cannot override final method A::finalPrivate()

Besides the error occurring, the message mentions overriding which isn't applicable for private methods.

With the implementation of this RFC, the previous and the following code would compile correctly:

<?php
 
class A 
{ 
    function callYourPrivate() { 
        $this->myPrivate(); 
    }
 
    function notOverriden_callYourPrivate() {
        $this->myPrivate(); 
    } 
    final private function myPrivate() { 
        echo __METHOD__ . PHP_EOL;
    } 
}
 
class B extends A 
{ 
    function callYourPrivate() {
        $this->myPrivate(); 
    } 
    private function myPrivate() { 
        echo __METHOD__ . PHP_EOL; 
    } 
}
 
$a = new A(); 
$a->callYourPrivate(); 
$a->notOverriden_callYourPrivate();
 
$b = new B(); 
$b->callYourPrivate(); 
$b->notOverriden_callYourPrivate();  

And would produce:

Warning: Private methods cannot be final as they are never overridden by other classes in ...
A::myPrivate
A::myPrivate
B::myPrivate
A::myPrivate

The final keyword when applied to a private method should have no significance. In most cases, a correct approach is to use final protected modifiers in a function where overriding is not desired.

NOTE: Due to how common the usage of final private function __construct is and given that the same results cannot be achieved with a protected visibility, an exception to this rule is made for constructors. With this exception, they are the only case where a child class can't override a final private method.

Backward Incompatible Changes

The new compiler warning:

Warning: Private methods cannot be final as they are never overridden by other classes in ...

Will start appearing in some code bases where both modifiers final and private are used. However, given that an exception is made for the most common case final private function __construct, I believe the warning is useful to let users know about this change.

Proposed PHP Version(s)

PHP 8.0

Unaffected PHP Functionality

The inheritance rules for visible methods remains unaffected, including when these are static or declared on a trait.

Vote

Voting started 2020-06-15 and ends 2020-06-29.

Vote: Remove inappropriate inheritance signature checks on private methods — Yes: 24 · No: 11 (closed)

Patches and Tests

Implementation: https://github.com/php/php-src/pull/5401