php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #71271 Allow final abstract class {}
Submitted: 2016-01-04 05:21 UTC Modified: 2020-05-16 20:38 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: andreas at dqxtech dot net Assigned:
Status: Wont fix Package: Class/Object related
PHP Version: 7.0.2RC1 OS:
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2016-01-04 05:21 UTC] andreas at dqxtech dot net
Description:
------------
It should be allowed to make a class both final and abstract, to make it a place for static methods. There is no good reason to not allow this.

It is already possible to achieve the same or a similar effect with final + a private constructor. But this is unnecessarily verbose.

Test script:
---------------
<?php

abstract final class C {
  static function foo() {}
}

Expected result:
----------------
should work just fine.

Actual result:
--------------
Fatal error: Cannot use the final modifier on an abstract class

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-01-04 05:31 UTC] requinix@php.net
-Status: Open +Status: Wont fix
 [2016-01-04 05:31 UTC] requinix@php.net
The idea was considered and declined. https://wiki.php.net/rfc/abstract_final_class
 [2016-01-04 05:43 UTC] andreas at dqxtech dot net
Is there any discussion I could have a look at, that explains why the RFC was discarded by most participants?

Also, what I propose is not really the same, it is much simpler: Allow the combination of the two keywords, with the regular natural consequences.
abstract: Cannot instantiate.
final: Cannot inherit.

I do NOT propose that a final + abstract class should only have static members.

I think it would be a bad idea to enforce this on the language level.
On the other hand, an IDE could very well notify people about the pointlessness of non-static methods within a final abstract class.

Unlike the RFC, this simple proposal adds no confusion and no magic. Everything will behave as one would expect.
 [2016-01-04 05:50 UTC] andreas at dqxtech dot net
It seems this is the discussion:
https://github.com/php/php-src/pull/923
 [2016-01-04 06:16 UTC] requinix@php.net
Original RFC thread: http://marc.info/?l=php-internals&m=141706013928872&w=2
Thread renamed: http://marc.info/?l=php-internals&m=141744239115034&w=2
Vote: http://marc.info/?l=php-internals&m=141840083023519&w=2

Your abstract+final idea was one of the options (the first one, even) but it looks like full static classes had more support. After all, if you can't instantiate the class and you can't extend it, what else can you do with it besides use static members?

You're free to bring up the subject on the internals list, naturally. However it's only been a year so I wouldn't expect opinions to have changed much.
 [2016-01-04 07:29 UTC] andreas at dqxtech dot net
> Your abstract+final idea was one of the options (the first one, even) but it looks like full static classes had more support.

Well, as I understand the RFC, and the discussion on the PR, the plan was to make the language prevent you from creating non-static methods in the class. So it would do more than just allow the keyword combo. While this would make sense in some way, it also would break user expectations, imo. A user should expect that combining two known keywords just has the combined effects of each keyword, but no additional extra effect.

If an extra effect is intended, I would rather opt for the other option, the "static class", and allow users to make it a "final static class" if they wish.
This appears attractive at first sight, but then there is the debate of whether to make the "static" keyword implicit or explicit. Whichever option is chosen, it will be a new thing for people to learn an remember.

The combo of abstract + final may look ugly, but it is a combination of well-known and well-understood language features, so it would be very predictable - if it is implemented without any creative extra behavior.

Finally, I don't see why utility classes are considered an anti-pattern. I think they are perfectly fine.
Global functions, even with namespace + autoloading, would mean to have a separate directory structure of source files for procedural code, in addition to the PSR-4 or PSR-0 directory structure for classes.
And the function autoloading would be yet another thing to learn and babysit.

Besides: No matter if you like them or not, utility classes are being used today.

Currently I let my utility classes "extends UtilBase". UtilBase has a "final private function __construct() {}", which maybe is even better than "final abstract class". But it means I have a number of these "UtilBase" classes, up to one per package.


> After all, if you can't instantiate the class and you can't extend it, what else can you do with it besides use static members?

Well.. generally I only put static members into my utility classes.
But, for the record, I currently have a use case where some of these non-instantiable classes inherit from an interface, with non-static methods.
This is only for a discovery mechanism, which will assume that an annotated static method will return an object which then generates objects of the provided interface. So I am using the interface like a meta-tag.
This is quite exotic, obviously, and not the common way to use interfaces...


> You're free to bring up the subject on the internals list, naturally. However it's only been a year so I wouldn't expect opinions to have changed much.

Maybe I will :)
 [2020-05-16 13:42 UTC] rnealxp at yahoo dot com
I went to submit this legitimate request that php should make allowance for "final abstract class". It is not right that this previous request was declined. It makes very good sense to have a class that both cannot be extended and that cannot be instantiated, since it contains only static functions (for use in organizing a code-library). It is a no-brainer.
 [2020-05-16 20:38 UTC] requinix@php.net
https://wiki.php.net/rfc/howto

It's been four years so that might be enough time for people to have reconsidered. But like I said last time, note that "static" classes had more support than "abstract final" classes.
 
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Sun Nov 29 14:01:24 2020 UTC