Good reasons to prohibit inheritance in Java?

JavaInheritanceFinal

Java Problem Overview


What are good reasons to prohibit inheritance in Java, for example by using final classes or classes using a single, private parameterless constructor? What are good reasons of making a method final?

Java Solutions


Solution 1 - Java

Your best reference here is Item 19 of Joshua Bloch's excellent book "Effective Java", called "Design and document for inheritance or else prohibit it". (It's item 17 in the second edition and item 15 in the first edition.) You should really read it, but I'll summarize.

The interaction of inherited classes with their parents can be surprising and unpredictable if the ancestor wasn't designed to be inherited from.

Classes should therefore come in two kinds:

  1. Classes designed to be **extended**, and with enough documentation to describe how it should be done

  2. Classes marked **final**

If you are writing purely internal code, this may be a bit of overkill. However, the extra effort involved in adding five characters to a class file is very small. If you are writing only for internal consumption, then a future coder can always remove the 'final' - you can think of it as a warning saying "this class was not designed with inheritance in mind".

Solution 2 - Java

You might want to make a method final so that overriding classes can't change behavior that is counted on in other methods. Methods called in constructors are often declared final so you don't get any unpleasant surprises when creating objects.

Solution 3 - Java

One reason to make a class final would be if you wanted to force composition over inheritance. This is generally desirable in avoiding tight coupling between classes.

Solution 4 - Java

There are 3 use cases where you can go for final methods.

  1. To avoid derived class from overriding a particular base class functionality.
  2. This is for security purpose, where base class is giving some important core functionality of the framework where derived class is not supposed to change it.
  3. Final methods are faster than instance methods, as there is no use of virtual table concept for final and private methods. So where ever there is a possibility, try to use final methods.

Purpose for making a class final:

So that no body can extend those classes and change their behavior.

Eg: Wrapper class Integer is a final class. If that class is not final, then any one can extend Integer into his own class and change the basic behavior of integer class. To avoid this, java made all wrapper classes as final classes.

Solution 5 - Java

you might want to make immutable objects (http://en.wikipedia.org/wiki/Immutable_object), you might want to create a singleton (http://en.wikipedia.org/wiki/Singleton_pattern), or you might want to prevent someone from overriding the method for reasons of efficiency, safety, or security.

Solution 6 - Java

Inheritance is like a chainsaw - very powerful, but awful in the wrong hands. Either you design a class to be inherited from (which can limit flexibility and take a lot longer) or you should prohibit it.

See Effective Java 2nd edition items 16 and 17, or my blog post "Inheritance Tax".

Solution 7 - Java

Hmmm... I can think of two things:

You might have a class that deals with certain security issues. By subclassing it and feeding your system the subclassed version of it, an attacker can circumvent security restrictions. E.g. your application might support plugins and if a plugin can just subclass your security relevant classes, it can use this trick to somehow smuggle a subclassed version of it into place. However, this is rather something Sun has to deal with regarding applets and the like, maybe not such a realistic case.

A much more realistic one is to avoid an object becomes mutable. E.g. since Strings are immutable, your code can safely keep references to it

 String blah = someOtherString;

instead of copying the string first. However, if you can subclass String, you can add methods to it that allow the string value to be modified, now no code can rely anymore that the string will stay the same if it just copies the string as above, instead it must duplicate the string.

Solution 8 - Java

To stop people from doing things that could confuse themselves and others. Imagine a physics library where you have some defined constants or calculations. Without using the final keyword, someone could come along and redefine basic calculations or constants that should NEVER change.

Solution 9 - Java

Also, if you are writing a commercial closed source class, you might not want people to be able to change the functionality down the line, especially if u need to give support for it and people have overridden your method and are complaining that calling it gives unexpected results.

Solution 10 - Java

If you mark classes and methods as final, you may notice a small performance gain, since the runtime doesn't have to look up the right class method to invoke for a given object. Non-final methods are marked as virtual so that they can be properly extended if needed, final methods can be directly linked or compiled inline in the class.

Solution 11 - Java

You want to make a method final so that overriding classes does not change its behavior. When you want to be able to change the behavior make the method public. When you override a public method it can be changed.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestioncretzelView Question on Stackoverflow
Solution 1 - JavaDJClayworthView Answer on Stackoverflow
Solution 2 - JavaBill the LizardView Answer on Stackoverflow
Solution 3 - JavaJohn TopleyView Answer on Stackoverflow
Solution 4 - Javauser1923551View Answer on Stackoverflow
Solution 5 - JavaRay TayekView Answer on Stackoverflow
Solution 6 - JavaJon SkeetView Answer on Stackoverflow
Solution 7 - JavaMeckiView Answer on Stackoverflow
Solution 8 - JavaAnson SmithView Answer on Stackoverflow
Solution 9 - JavaDavidGView Answer on Stackoverflow
Solution 10 - JavaseanalltogetherView Answer on Stackoverflow
Solution 11 - JavaAlexander RobinsonView Answer on Stackoverflow