I would like to add some nuance to the answer provided by Konrad Rudolph. While his response is certainly true in most contexts, it does not mention the situation where the code may be used as a dependency of another project.
The project that depends on this code may need to modify the behavior of the final class for a use case that was not anticipated by the original creator of the class (it is impossible to anticipate all situations), and marking the class as final could be quite problematic.
Let's imagine a scenario: I have coded a Symfony library that allows sending Batman-themed emails.
The template is customizable, as it is often the case with most Symfony libraries because of its native template overriding mechanism.
I have created a service that contains a method sendBatmanEmail(BatmanEmailDto $emailDto)
To use this service, the caller must initialize a BatmanEmailDto
, which offers two setters setSubject
and setText
.
The sendBatmanEmail
method does its job (at least 300 lines of code!), then passes the DTO to the template for rendering. The DTO is marked final.
In most cases, it works fine with a subject and a text! Some slight modifications are possible via the Symfony template overriding engine, which is the icing on the cake.
But if tomorrow a project wants to have two distinct texts in the template, or add an image, manipulate a richer entity, etc... The use of the library will be completely questioned since it will be impossible to extend the BatmanEmailDto
and pass more data to the template. The sendBatmanEmail
method will need to be rewritten entirely (or maybe entirely copy/pasted? good luck for the maintenance!..)
All of this is to say that if you are developing a library and not a final project, please avoid using final classes. It looks nice on paper, but for future dependencies of your project, it rarely seems like a good idea.
And I forgot to mention if you want to replace some class by dependency injection configuration, which is a very common type of usage in Magento for example (and is very maintainable if used with caution when and only when it is useful btw)
PS: if some developer is not clever enough to understand that your class is not made to be extended, he will probably not be clever enough to NOT remove your final keyword also.