I am refactoring a PHP OOP legacy website. 

I am so tempted to start using 'final' on classes to "make it explicit that the class is currently not extended by anything".  This might save lots of time if I come to a class and I am wondering if I can rename/delete/modify a protected property or method. If I really want to extend a class I can just remove the final keyword to unlock it for extending.

I.e If I come to a class that has no child classes I can record that knowledge by marking the class a final. The next time I come to it I would not have to re-search the codebase to see if it has children. Thus saving time during refactorings.

It all seems like a sensible time saving idea.... but I have often read that classes should only be made 'final' on rare/special occasions.

Maybe it screws up Mock object creation or has other side effects that I am not thinking of.

What am I missing? 


I have often read that classes should only be made 'final' on rare/special occasions.

Whoever wrote that is wrong. Use final liberally, there’s nothing wrong with that. It documents that a class wasn’t designed with inheritance in mind, and this is usually true for all classes by default: designing a class that can be meaningfully inherited from takes more than just removing a final specifier; it takes a lot of care.
So using final by default is by no means bad. In fact, amongst OOP experts it’s widely agreed that final should be the default, e.g. Jon Skeet:

Classes should be sealed by default in C#

Or Joshua Bloch:

Design and document for inheritance or else prohibit it [Effective Java, 3rd Ed, Item 19]

Or Scott Meyers [More Effective C++, Item 33].
Which is why modern OO langauges such as Kotlin have final-by-default classes.
You wrote:

Maybe it screws up Mock object creation …

And this is indeed a caveat, but you can always recourse to interfaces if you need to mock your classes. This is certainly superior to making all classes open to inheritance just for the purpose of mocking.
