Can anyone explain disadvantage of inheritance in java
you probably want to read:
Effective Java™, Second Edition By: Joshua Bloch
Chapter 4. Classes and Interfaces
Item 16: Favor composition over inheritance
Item 17: Design and document for inheritance or else prohibit it
Item 18: Prefer interfaces to abstract classes
Take a loot at Allen Holub's article in JavaWorld entitled Why extends is evil. He discusses things like tight-coupling and the fragile base class problem.
We prefer composition over inheritance because when we add (particularly) or change functionality by subclassing, we couple that new functionality to the class - so anywhere we need the new functionality, we need that class. That extends even to further subclasses - and with Java's single-inheritance model, if we have two new bits of functionality we want in yet another class, there's no (simple) way to bring both bits in, if each is in a separate subclass of the original ancestor.
By comparison, if we extend functionality via composition, any class - in or out of our existing hierarchy - can incorporate it by simply including the tiny class that has the new function. It's simpler, cleaner, more reusable, and easier to read.
Inheritance has its place, but it's not the right tool for many, many jobs.
Unless your class is designed for inheritance, it should be made final. You have to be very careful to make sure you understand how methods which will be overridden in a sub class which was not designed for inheritance function, so as to understand how to modify them.
A specific example:
Consider you have a class that manages a list of names...
public class MyNameManager {
private List<String> numbers = new LinkedList<String>();
public void add(String value) {
numbers.add(value);
}
public void addAll(Collection<String> values) {
for(String value : values) {
add(value);
}
}
public void remove(String value) { //... }
//...
}
Now say you want to create a new subclass which also counts the total number of times a name gets added to the list, like so:
public class MyCountingNameManager extends MyNameManager {
private int count = 0;
@Override
protected void addAll(Collection<String> values) {
count += values.size();
super.addAll(values);
}
@Override
protected void add(String value) {
count += 1;
super.add(value);
}
}
Seems pretty straightforward, no? But consider the result of the following:
MyCountingNameManager m = new MyCountingNameManager();
m.add("bob");
m.add("Sally");
The count is now 2, and all is well. But if we were to do the following:
List<String> family = new List<String>();
family.add("mom");
family.add("dad");
family.add("brother");
MyCountingNameManager m = new MyCountingNameManager();
m.add(family);
The count is now 6, not the 3 you'd probably expect. This is because the call to addAll
adds the size of the Collection of values (which is 3) to the count, and then calls the super.addAll
method to do the actual processing. super.addAll
iterates the Collection and calls the add
method for each value. But since we're working in an MyCountingNameManager
and not a MyNameManager
, the overridden add
method in the sub class is called each time. The MyCountingNameManager.add
method which gets executed also increments the count! So the result is each name gets counted twice!
I believe this example comes from Effective Java. You should definitely find a copy and read the items listed in Viele's answer for a deeper understanding of some cases where inheritance is a bad fit.