A sealed class can be extended directly only by the specified classes. Similarly, an interface that is sealed can be implemented directly only by the classes listed.
Classes mentioned in the sealing list can themselves be extended arbitrarily unless they are final or also sealed.
In this way, sealing provides a single-level restraint on inheritance.
The purpose of the feature should not be conflated or confused with the goals of something like package-private classes or namespace visibility, in general.
Support for sealed classes is added through a new keyword, seals
.
namespace Typing;
interface Type { ... }
class StringType implements Type { ... }
class IntegerType implements Type { ... }
class FloatType implements Type { ... }
sealed class UnionType permits NumberType, KeyType implements Type
{
public function __construct(
protected array $types
) {}
...
}
// ok
final class NumberType extends UnionType {
public function __construct() {
parent::__construct([new IntegerType, new FloatType]);
}
}
// ok
final class KeyType extends UnionType {
public function __construct() {
parent::__construct([new IntegerType, new StringType]);
}
}
// Error: Class ScalarType may not inherit from sealed class (UnionType)
final class ScalarType extends UnionType {
public function __construct() {
parent::__construct([new IntegerType, new FloatType, new StringType]);
}
}
sealed interface UserInterface permits ExtendedUserInterface, User
{
}
// ok
interface ExtendedUserInterface extends UserInterface
{
}
// ok
final class User implements UserInterface
{
}
// Error: Interface SuperUserInterface may not inherit from sealed interface (UserInterface)
interface SuperUserInterface extends UserInterface
{
}
// Error: Class MyUser may not inherit from sealed interface (UserInterface)
final class MyUser implements UserInterface
{
}
example from symfony/cache - simplified
namespace Symfony\Component\Cache\Traits {
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Component\Cache\Adapter\FilesystemTagAwareAdapter;
sealed trait FilesystemTrait permits FilesystemAdapter, FilesystemTagAwareAdapter { ... }
}
namespace Symfony\Component\Cache\Adapter {
use Symfony\Component\Cache\Traits\FilesystemTrait;
// ok
final class FilesystemAdapter {
use FilesystemTrait;
...
}
// ok
final class FilesystemTagAwareAdapter {
use FilesystemTrait;
...
}
}
namespace App\Cache {
use Symfony\Component\Cache\Traits\FilesystemTrait;
// Error: Class App\Cache\MyFilesystemCache may not use sealed trait (Symfony\Component\Cache\Traits\FilesystemTrait)
final class MyFilesystemAdapter {
use FilesystemTrait;
}
// Error: Trait App\Cache\MyFilesystemTrait may not use sealed trait (Symfony\Component\Cache\Traits\FilesystemTrait)
trait MyFilesystemTrait {
use FilesystemTrait;
}
}