When to use Final in PHP?
A final
class is one which cannot be extended http://php.net/manual/en/language.oop5.final.php
You would use it where the class contained methods which you specifically do not want overridden. This may be because doing do would break your application in some way.
There is a nice article about "When to declare classes final". A few quotes from it:
TL;DR: Make your classes always
final
, if they implement an interface, and no other public methods are definedWhy do I have to use
final
?
- Preventing massive inheritance chain of doom
- Encouraging composition
- Force the developer to think about user public API
- Force the developer to shrink an object's public API
- A
final
class can always be made extensibleextends
breaks encapsulation- You don't need that flexibility
- You are free to change the code
When to avoid
final
:Final classes only work effectively under following assumptions:
- There is an abstraction (interface) that the final class implements
- All of the public API of the final class is part of that interface
If one of these two pre-conditions is missing, then you will likely reach a point in time when you will make the class extensible, as your code is not truly relying on abstractions.
P.S. Thanks to @ocramius for great reading!
For general usage, I would recommend against making a class final
. There might be some use cases where it makes sense: if you design a complex API / framework and want to make sure that users of your framework can override only the parts of the functionality that you want them to control it might make sense for you to restrict this possibility and make certain base classes final
.
e.g. if you have an Integer
class, it might make sense to make that final
in order to keep users of your framework form overriding, say, the add(...)
method in your class.
The reason are:
Declaring a class as final prevents it from being subclassed—period; it’s the end of the line.
Declaring every method in a class as final allows the creation of subclasses, which have access to the parent class’s methods, but cannot override them. The subclasses can define additional methods of their own.
The final keyword controls only the ability to override and should not be confused with the private visibility modifier. A private method cannot be accessed by any other class; a final one can.
—— quoted from page 68 of the book PHP Object-Oriented Solutions by David Powers.
For example:
final childClassname extends ParentsClassname {
// class definition omitted
}
This covers the whole class, including all its methods and properties. Any attempt to create a child class from childClassname would now result in a fatal error. But,if you need to allow the class to be subclassed but prevent a particular method from being overridden, the final keyword goes in front of the method definition.
class childClassname extends parentClassname {
protected $numPages;
public function __construct($autor, $pages) {
$this->_autor = $autor;
$this->numPages = $pages;
}
final public function PageCount() {
return $this->numPages;
}
}
In this example, none of them will be able to overridden the PageCount()
method.