Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

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.

Have you ever treated final liberally and had bad experiences or is this 'fear of final' just a myth.

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

What am I missing?

share|improve this question
2  
If you have full control of your code, then it is not terrible, I suppose, but a bit on a OCD side. What if you miss a class (e.g it has no children but it aint final)? It is better let a tool scan the code and tell you whether some class has children. As soon as you package this as a library and give it to someone else, dealing with 'final' becomes a pain. –  Job Jul 2 '11 at 13:58
    
For example, MbUnit is an open framework for .Net unit testing, and MsTest ain't (surprise surprise). As the result, you HAVE to shell out 5k to MSFT just because you want to run some tests the MSFT way. Other test runners cannot run the test dll that is built with MsTest - all because of the final classes that MSFT used. –  Job Jul 7 '11 at 4:24
1  
Some blog post about the topic: Final Classes: Open for Extension, Closed for Inheritance (May 2014; by Mathias Verraes) –  hakre May 18 at 16:16
    
Nice article. It speaks my thoughts about this. I did not know about those annotations so that was handy. Cheers. –  JW01 May 21 at 19:54

5 Answers 5

up vote 18 down vote accepted

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.

share|improve this answer
1  
1+: Since it screws up mocking; consider creating interfaces or abstract classes for each "final" class. –  Spoike Jul 14 '11 at 11:49
    
Well that puts a spanner in the works. This late arrival contradicts all the other answers. Now I do not know what to believe :o. (Unticked my accepted answer and hold off decision during re-trial) –  JW01 Jul 14 '11 at 16:18
1  
You can consider the Java API itself and how often you will find the usage of the 'final' keyword. In fact, it is not used very often. It is used in cases were performance might get bad due to the dynamic binding taking place when "virtual" methods are called (in Java all methods are virtual if they are not declared as 'final' or 'private'), or when introducing custom subclasses of a Java API class might arise consistency issues, such as subclassing 'java.lang.String'. A Java String is a value object per definition and must not change its value later on. A subclass could break this rule. –  Jonny Dee Jul 16 '11 at 20:46
3  
@Jonny Most of the Java API is badly designed. Remember that the bulk of it is more than ten years old and many best practices have been developed in the meantime. But don’t take my word for it: the Java engineers themselves say so, first and foremost Josh Bloch who has written in detail about this, e.g. in Effective Java. Rest assured that if the Java API were developed today, it would look very different, and final would play a much bigger role. –  Konrad Rudolph Jul 17 '11 at 10:07
1  
I'm still not convinced that using 'final' more often has become a best practice. In my opinion, the 'final' should really be used only if performance requirements dictate it, or if you must assure consistency cannot be broken by subclasses. In all other cases necessary documentation should go into, well, the documentation (which needs to be written anyway), and not into the source code as keywords that enforce certain usage patterns. To me, that's kind of playing god. Using annotations whould be a better solution. One could add a '@final' annotation and the compiler could issue a warning. –  Jonny Dee Jul 17 '11 at 17:47

If you want to leave a note to yourself that a class has no sub-classes, then by all means do so and use a comment, thats what they are for. The "final" keyword is not a comment, and using language keywords just to signal something to you (and only you would ever know what it means) is a bad idea.

share|improve this answer
6  
This is completely false! “ using language keywords just to signal something to you […] is a bad idea.” – On the contrary, that is exactly what language keywords are there for. Your tentative caveat, “and only you would ever know what it means”, is of course correct but doesn’t apply here; the OP is using final as expected. There’s nothing wrong with that. And using a language feature to enforce a constraint is always superior to using a comment. –  Konrad Rudolph Jul 14 '11 at 6:51
3  
@Konrad: Except final should denote "No subclass of this class should ever be created" (for legal reasons or something), not "this class currently has no children, so I'm still safe to mess with its protected members". The intent of final is the very antithesis of "freely editable", and a final class shouldn't even have any protected members! –  SF. Jul 14 '11 at 7:10
1  
@Konrad Rudolph It is not miniscule at all. If other people later want to extend his classes, there is a big difference between a comment that says "not extended" and a keyword that says "may not extend". –  Jeremy Jul 14 '11 at 13:39
1  
@Konrad Rudolph That sounds like a great opinion to bring to a question about OOP language design. But we know how PHP works, and it takes the other approach of allowing extension unless sealed. Pretending that its ok to conflate keywords because "thats how it should be" is just defensiveness. –  Jeremy Jul 14 '11 at 14:35
1  
@Jeremy I’m not conflating keywords. The keyword final means, “this class is not to be extended [for now].” Nothing more, nothing less. Whether PHP was designed with this philosophy in mind is irrelevant: it has the final keyword, after all. Secondly, arguing from PHP’s design is bound to fail, given how patchworky and just overall badly PHP is designed. –  Konrad Rudolph Jul 14 '11 at 14:38

One thing you may not have thought of is the fact that ANY change of a class means that it has to undergo new QA-testing.

Do not mark things as final unless you really, really mean it.

share|improve this answer
    
Thanks. Could you explain that further. Do you mean that if I mark a class as final (a change) then I just have to re-test it? –  JW01 Jul 2 '11 at 12:18
3  
I would say this more strongly. Do not mark things as final unless an extension cannot be made to work because of the design of the class. –  S.Lott Jul 2 '11 at 12:18
    
Thanks S.Lott - I am trying to understand how bad use of final affects the code/ project. Have you experienced any bad horror stories that have lead you to be so dogmatic about the sparing use of final. Is this first hand experience? –  JW01 Jul 2 '11 at 12:27
1  
@JW01: A final class has one primary use case. You have polymorphic classes that you do not want extended because a subclass might break polymorphism. Don't use final unless you must prevent the creation of subclasses. Other than that, it's useless. –  S.Lott Jul 2 '11 at 12:36
    
Thanks S.Lott. You could submit that as an answer. –  JW01 Jul 2 '11 at 12:40

Using 'final' takes away freedom of others that want to use your code.

If the code you write is only for you and will never be released to the public or a customer then you can do with your code what you want, of course. Otherwise, you prevent others from building upon your code. Too often have I had to work with an API that would have been easy to extend for my needs, but then I was hindered by 'final'.

Also, there is often code that should better not be made private, but protected. Sure, private means "encapsulation" and hide things considered to be implementation details. But as an API programmer I might as well document the fact that method xyz is considered to be implementation detail and, thus, may be changed/deleted in future version. So everyone who will rely on such code in spite of the warning is doing it on his own risk. But he can actually do it and reuse (hopefully already tested) code and come up faster with a solution.

Of course, if the API implementation is open source one can just remove the 'final' or make methods 'protected', but than you have changed the code and need to track your changes in form of patches.

However, if the implementation is closed source you are left behind with finding a workaround or, in the worst case, with switching to another API with less restrictions regarding possibilities for customization/extension.

Note that I don't find 'final' or 'private' are evil, but I think they are just used too often because the programmer didn't think about his code in terms of code reuse and extension.

share|improve this answer
1  
"Inheritance is not code reuse". –  quant_dev Jul 2 '11 at 21:00
2  
Ok, if you insist on a perfect definition you're right. Inheritance expresses an 'is-a' relationship and it is this fact which allows for polymorphism and provides a way of extending an API. But in practice, inheritance is very very often used to reuse code. This is especially the case with multiple inheritance. And as soon as you call code of a super class you are actually reusing code. –  Jonny Dee Jul 2 '11 at 21:33
1  
btw, a very short comment for a -2 down vote, thanx. –  Jonny Dee Jul 2 '11 at 21:51
    
Oh stop whinging, nobody likes that. –  quant_dev Jul 3 '11 at 10:27
1  
@quant_dev: You get reuseability in the OOP sense wrong. It means that a single method can operate on many datatypes, thanks to interface sharing. That's a major part of OOP code reuse. And inheritance automatically let's us share interfaces, thus enhacing code reuseability greatly. That's why we talk about reusability in OOP. Just creating libraries with routines is nearly as old as programming itself and can be done with almost every language, it's common. Code-Reuse in OOP is more than that. –  Falcon Jul 18 '11 at 8:32

it will question the OO (Object Orientation) most important feature, i.e, Extensibility.. you can 'final' a class but make sure, the class has all the methods perfectly made. For if you try to make some changes later, then you won't be able to do it! Though, sometimes, making a class is an option, since, you don't any other programmer to come and change the safety of your class and put some really scary things.. Enjoy Programming :)

share|improve this answer
1  
this doesn't add anything substantial over points made and explained in a prior answer that was posted 3 years ago –  gnat Jun 23 at 8:49

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.