final classes
In the past, when you didn't want other classes to extend a certain class, you could mark it as final
.
Consider the code below :
<?php
namespace App\Utils;
class ParentClass
{
public function __construct(protected string $name) {
}
}
<?php
namespace App\Utils;
class ChildClass extends ParentClass
{
}
So we have a ParentClass
and a ChildClass
that extends the parent.
we could use the ChildClass
as following:
<?php
use App\Utils\ChildClass;
$obj = new ChildClass('Antonio');
var_dump($obj);
And this would output ChildClass
public properties and also inherited properties from ParentClass
as follows:
Now if we do not want our class to be extended we just put the word final
at the beginning of the class as follows:
<?php
namespace App\Utils;
final class ParentClass
{
public function __construct(
protected string $name,
) {
}
}
and calling the $obj = new ChildClass('Antonio');
again would result in: Class App\Utils\ChildClass cannot extend final class App\Utils\ParentClass
.
So the definition of final
in php is:
The final keyword is used to prevent a class from being inherited and to prevent inherited method from being overridden.
- So if we declare class method as a
final
then that method cannot be override by the child class. - Same as method if we declare class as a
final
then that class cannot be extended any more.
readonly class
readonly
classes are added on PHP 8.2
.
final
and readonly
are two completely different concepts in PHP and have different implications when applied to a class.
As we saw earlier, making a class final
means that it cannot be extended.
final class ParentClass{}
// Fatal error: Class ChildClass cannot extend final class ParentClass
class ChildClass extends ParentClass{}
In the other hand, making a class readonly
means several things:
- All instance properties of a class are implicitly marked as readonly, and cannot be reassigned.
- Creation of dynamic properties is not allowed.
- Only a readonly class can extend another readonly class.
- readonly properties can be overridden
For example:
// PHP 8.2+
readonly class ParentClass
{
public function __construct(
public string $name
) {}
}
$obj = new ParentClass('Antonio');
echo 'Hello, My name is ' . $obj ->name; // "Hello, My name is Antonio"
If you try to re-assign a value to any object property after instantiation, it would throw the following error:
// PHP 8.2+
// Fatal error: Uncaught Error: Cannot modify readonly property ParentClass::$name
$obj ->name = 'Ndershkuesi';
This happens because all properties are implicitly readonly when you mark the class as readonly.
NOTE: readonly
property cannot have default value.
final and readonly
You can also mark a class as both readonly
and final
as well, this means:
- All class properties are implicitly
readonly
. - The class cannot be extended.
Example:
// PHP 8.2+
final readonly class ParentClass {
public function __construct(
public string $name
) {}
}
Usage:
$obj = new ParentClass('Antonio');
echo 'My name is ' . $obj->name; // "My name is Antonio"
And if you try to assign a value to any object property or if you try to extend the class then it would throw an error as follows:
// PHP 8.2+
// Fatal error: Uncaught Error: Cannot modify readonly property ParentClass::$name
$obj->name = 'Ndershkuesi';
// Fatal error: Class ChildClass cannot extend final class Shape
readonly class ChildClass extends ParentClass {}
Was it helpful?
Let me know in the comment section below if you ever use this package in any of your projects.
Don’t forget to like and comment.
Follow me for more web development tips, new packages and more.
Thanks for reading.
Top comments (1)
Thanks for you effort. You still have a case that a readonly class extends readonly ParentClass. How are the constructors?