Skip to content

Instantly share code, notes, and snippets.

@brzuchal
Created March 19, 2019 11:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brzuchal/70ba671d23f8d4d4bd70d2f14118d328 to your computer and use it in GitHub Desktop.
Save brzuchal/70ba671d23f8d4d4bd70d2f14118d328 to your computer and use it in GitHub Desktop.
Sealed classes RFC

Sealed classes

Introduction

A sealed type is one for which subclassing is restricted according to subclass names specified with the class’s declaration or to restrict to the same subclass namespace.

Sealed type is more like extended form of finality, where it is possible to list all class names allowed to extending from sealed class or permit only same namespace class to extend sealed class.

Purpose of sealing is that it restricts who can be a subtype. This is largely a declaration-site concern, where an API owner wants to defend the integrity of their API.

Proposal

Sealed class with permits list

We specify that a class is sealed by applying the sealed modifier to a class, abstract class, or interface, with an optional permits list:

sealed interface Node
     permits A, B, C { ... }

In this explicit form, Node may be extended only by the types enumerated in the permits list. This means further extending a Node class will raise a compile time error.

sealed interface Node
     permits A { ... }
class Foo extends Node { ... } // Compile time error as Foo is not listed in permits clause

Sealed class allows own namespace classes for extending

In case we not tend to list all allowed class names it is possible to seal a class and allow extending in the same namespace without specifying permits.

namespace MyTree;

sealed class Node { ... }

class Leaf extends Node { ... }

Which means all allowed extending classes must further be members of the same namespace.

Inheritcance

Unless otherwise specified, abstract subtypes of sealed types are implicitly sealed, and concrete subtypes are implicitly final.

Anonymous classes

Anonymous subclasses of a sealed type are prohibited.

Backward Incompatible Changes

sealed and permits keywords become reserved word.

Proposed PHP Version

This is proposed for the next version of PHP, currently PHP 7.4.

RFC Impact

To Reflection

The following additions will be made to expose the new flag via reflection:

  • New constant ReflectionClass::IS_SEALED to expose the bit flag used for sealed classes
  • The return value of ReflectionClass::getModifiers() will have this bit set if the class being reflected is sealed
  • Reflection::getModifierNames() will include the string "sealed” if this bit is set
  • A new ReflectionClass::isSealed() method will allow directly checking if a class is locked
  • A new ReflectionClass::getPermits() method will include a list of allowed subclasses

To Existing Extensions

None.

To Opcache

The RFC's compatibility with opcache is yet to be verified. It merely adds a new ZEND_ACC_SEALED flag so support shouldn't be a problem, however.

Unaffected PHP Functionality

This does not affect methods or static properties.

Proposed Voting Choices

As this is a language change, a 2/3 majority is required.

Patches and Tests

TBD

Implementation

After the project is implemented, this section should contain

  1. the version(s) it was merged to
  2. a link to the git commit(s)
  3. a link to the PHP manual entry for the feature

References

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment