# RFC: Allow abstract function override

- Status: Implemented (PHP 7.2)
- Authors: @WesNetmo @ Twitter
- Date: 2017-03-01
- Version: 0.1
- Original: https://wiki.php.net/rfc/allow-abstract-function-override
- Page: https://externals.io/rfc/allow-abstract-function-override
- More for agents: search with https://externals.io/search.md?q={query} · RFCs at https://externals.io/rfc.md · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

## Votes

### Accept abstract function override? (closed)

Yes: 16 · No: 3

Voters: ashnazg (No), bwoebi (Yes), cyberline (Yes), daverandom (Yes), dm (Yes), emir (Yes), galvao (Yes), kelunik (Yes), kguest (Yes), marcio (Yes), mariano (No), ocramius (Yes), patrickallaert (No), salathe (Yes), sammyk (Yes), stas (Yes), subjective (Yes), treffynnon (Yes), trowski (Yes)

## Discussions on the mailing list

- [\[RFC\]\[DISCUSSION\] Allow abstract function override](https://externals.io/message/98365.md) — started on 2017-03-01, 3 messages
- [\[RFC\]\[VOTE\] Allow abstract function override](https://externals.io/message/98646.md) — started on 2017-03-28, 15 messages

---

## Proposal

PHP 7 introduced type declarations for return and improved ones for parameters. They currently support a very limited kind of variance (only to no-type):

```php
<?php
class A           { function bar(stdClass $x){}  }
class B extends A { function bar($x): stdClass{} }
```

However, this isn't currently matched by the equivalent abstract declarations:

```php
<?php
abstract class A           { abstract function bar(stdClass $x);  }
abstract class B extends A { abstract function bar($x): stdClass; }
class C extends B          { function bar($x): stdClass{} }
// Fatal error: Can't inherit abstract function A::bar()
// (previously declared abstract in B)
```

This RFC proposes to allow this, even if it has very few uses, and because there is no reason to disallow a compatible redefinition.

Additionally, it comes in handy for documentation:

```php
interface A{
    function doSomething();
}
 
interface B extends A{
    function doSomethingElse();
}
 
abstract class AProxy implements A{
    abstract protected function getOrigin(): A;
    function doSomething(){
        return $this->getOrigin()->doSomething();
    }
}
 
// This phpdoc syntax has quirks in phpdocumentor
// apigen and phpstorm, and it's almost unmanageable
// as phpdoc interpreters have poor multiline support
// (imagine documenting all the parameters, the return
// type, all the throws...):
/** @method B getOrigin() */
abstract class BProxy extends AProxy implements B{
    /** @return B */ // This is much better!
    abstract protected function getOrigin(): A;
    function doSomethingElse(){
        return $this->getOrigin()->doSomethingElse();
    }
}
```

And, obviously, it will gain more uses when PHP will support a full-featured type variance.

## Backward Incompatible Changes

None.

## Proposed PHP Version(s)

7.2

## Voting

2/3 majority required.

**Vote: Accept abstract function override?** — Yes: 16 · No: 3 (closed)

## Patches and Tests

Pull request to handle the change: <https://github.com/php/php-src/pull/2531>

## References

[Discussion on externals.io](https://externals.io/thread/735)
