PHP OOP – Why Is Using ‘Final’ on a Class Considered Bad?

finalobject-orientedPHP

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?

Best Answer

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, many people propose that this should be the default, e.g. Jon Skeet.

Maybe it screws up Mock object creation …

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.