Inheritance BreaksWeakens Encapsulation
When you publish an interface with inheritance permitted, you substantially increase the size of your interface. Specifically, insteadEach overrideable method could be replaced and so should be thought of justas callback provided to the constructor. The implementation provided by your public methods being publicclass is merely the default value of the callback. Thus, allsome kind of your calls to your public methodscontract should be provided indicating what the expectations on the method are public. HereThis seldom happens and is a major reason why object oriented code is called brittle.
Below is a real (simplified) example from the java collections framework, courtesy of Peter Norvig (http://norvig.com/java-iaq.html).
Public Class HashTable{
...
Public Object put(K key, V value){
try{
//add object to table;
}catch(TableFullException e){
increaseTableSize();
put(key,value);
}
}
}
So what happens if we subclass this?
/** A version of Hashtable that lets you do
* table.put("dog", "canine");, and then have
* table.get("dogs") return "canine". **/
public class HashtableWithPlurals extends Hashtable {
/** Make the table map both key and key + "s" to value. **/
public Object put(Object key, Object value) {
super.put(key + "s", value);
return super.put(key, value);
}
}
We have a bug: Occasionally we add "dog" and the hashtable gets an entry for "dogss". The cause was someone providing an implementation of put that the person designing the Hashtable class did not expect.
Note that this is not a problem with recursion, this can happen any time that a class calls one of its own public methods. In reality, there may well be several levels of inheritance involved in the problem.
This can be resolved by committing to not call the public methods of a class in that class. In practice, this commitment is frequently not honoured and is a major reason why object oriented code is considered "brittle".
Inheritance Breaks Extensibility
If you allow your class to be subclassed, you are committing to not add any methods to your class. This could otherwise be done without breaking anything.
When you add new methods to an interface, anyone who has inherited from your class will need to implement those methods.